Clang format (#55)

Run clang-format on modules of code
This commit is contained in:
Thomas Ramstad 2021-11-08 22:58:37 +01:00 committed by GitHub
parent f29ae0b0bc
commit 23189f5577
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
104 changed files with 56746 additions and 49196 deletions

View File

@ -1,108 +1,13 @@
# To run clang tools: # clang-format
# 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 {}
--- ---
Language: Cpp Language: Cpp
# BasedOnStyle: LLVM BasedOnStyle: LLVM
AccessModifierOffset: -4 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 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
...

View File

@ -1,33 +1,54 @@
#include "analysis/ElectroChemistry.h" #include "analysis/ElectroChemistry.h"
ElectroChemistryAnalyzer::ElectroChemistryAnalyzer(std::shared_ptr<Domain> dm)
: Dm(dm) {
ElectroChemistryAnalyzer::ElectroChemistryAnalyzer(std::shared_ptr <Domain> dm): Nx = dm->Nx;
Dm(dm) 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; ChemicalPotential.resize(Nx, Ny, Nz);
Volume=(Nx-2)*(Ny-2)*(Nz-2)*Dm->nprocx()*Dm->nprocy()*Dm->nprocz()*1.0; ChemicalPotential.fill(0);
ElectricalPotential.resize(Nx, Ny, Nz);
ChemicalPotential.resize(Nx,Ny,Nz); ChemicalPotential.fill(0); ElectricalPotential.fill(0);
ElectricalPotential.resize(Nx,Ny,Nz); ElectricalPotential.fill(0); ElectricalField_x.resize(Nx, Ny, Nz);
ElectricalField_x.resize(Nx,Ny,Nz); ElectricalField_x.fill(0); ElectricalField_x.fill(0);
ElectricalField_y.resize(Nx,Ny,Nz); ElectricalField_y.fill(0); ElectricalField_y.resize(Nx, Ny, Nz);
ElectricalField_z.resize(Nx,Ny,Nz); ElectricalField_z.fill(0); ElectricalField_y.fill(0);
Pressure.resize(Nx,Ny,Nz); Pressure.fill(0); ElectricalField_z.resize(Nx, Ny, Nz);
Rho.resize(Nx,Ny,Nz); Rho.fill(0); ElectricalField_z.fill(0);
Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field Pressure.resize(Nx, Ny, Nz);
Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0); Pressure.fill(0);
Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0); Rho.resize(Nx, Ny, Nz);
SDs.resize(Nx,Ny,Nz); SDs.fill(0); Rho.fill(0);
IonFluxDiffusive_x.resize(Nx,Ny,Nz); IonFluxDiffusive_x.fill(0); Vel_x.resize(Nx, Ny, Nz);
IonFluxDiffusive_y.resize(Nx,Ny,Nz); IonFluxDiffusive_y.fill(0); Vel_x.fill(0); // Gradient of the phase indicator field
IonFluxDiffusive_z.resize(Nx,Ny,Nz); IonFluxDiffusive_z.fill(0); Vel_y.resize(Nx, Ny, Nz);
IonFluxAdvective_x.resize(Nx,Ny,Nz); IonFluxAdvective_x.fill(0); Vel_y.fill(0);
IonFluxAdvective_y.resize(Nx,Ny,Nz); IonFluxAdvective_y.fill(0); Vel_z.resize(Nx, Ny, Nz);
IonFluxAdvective_z.resize(Nx,Ny,Nz); IonFluxAdvective_z.fill(0); Vel_z.fill(0);
IonFluxElectrical_x.resize(Nx,Ny,Nz); IonFluxElectrical_x.fill(0); SDs.resize(Nx, Ny, Nz);
IonFluxElectrical_y.resize(Nx,Ny,Nz); IonFluxElectrical_y.fill(0); SDs.fill(0);
IonFluxElectrical_z.resize(Nx,Ny,Nz); IonFluxElectrical_z.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) { if (Dm->rank() == 0) {
bool WriteHeader = false; bool WriteHeader = false;
@ -38,14 +59,12 @@ ElectroChemistryAnalyzer::ElectroChemistryAnalyzer(std::shared_ptr <Domain> dm):
WriteHeader = true; WriteHeader = true;
TIMELOG = fopen("electrokinetic.csv", "a+"); TIMELOG = fopen("electrokinetic.csv", "a+");
if (WriteHeader) if (WriteHeader) {
{
// If timelog is empty, write a short header to list the averages // If timelog is empty, write a short header to list the averages
//fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n"); //fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n");
fprintf(TIMELOG, "TBD TBD\n"); fprintf(TIMELOG, "TBD TBD\n");
} }
} }
} }
ElectroChemistryAnalyzer::~ElectroChemistryAnalyzer() { ElectroChemistryAnalyzer::~ElectroChemistryAnalyzer() {
@ -54,11 +73,11 @@ ElectroChemistryAnalyzer::~ElectroChemistryAnalyzer(){
} }
} }
void ElectroChemistryAnalyzer::SetParams(){ void ElectroChemistryAnalyzer::SetParams() {}
} void ElectroChemistryAnalyzer::Basic(ScaLBL_IonModel &Ion,
ScaLBL_Poisson &Poisson,
void ElectroChemistryAnalyzer::Basic(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson, ScaLBL_StokesModel &Stokes, int timestep){ ScaLBL_StokesModel &Stokes, int timestep) {
int i, j, k; int i, j, k;
double Vin = 0.0; double Vin = 0.0;
@ -102,13 +121,16 @@ void ElectroChemistryAnalyzer::Basic(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poiss
for (i = 1; i < Nx; i++) { for (i = 1; i < Nx; i++) {
rho_avg_local[ion] += Rho(i, j, k); rho_avg_local[ion] += Rho(i, j, k);
rho_mu_avg_local[ion] += Rho(i, j, k) * 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_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_mu_avg_global[ion] =
rho_psi_avg_global[ion]=Dm->Comm.sumReduce( rho_psi_avg_local[ion]) / Volume; 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) { if (rho_avg_global[ion] > 0.0) {
rho_mu_avg_global[ion] /= rho_avg_global[ion]; 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 (k = 1; k < Nz; k++) {
for (j = 1; j < Ny; j++) { for (j = 1; j < Ny; j++) {
for (i = 1; i < Nx; i++) { 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_mu_fluctuation_local[ion] +=
rho_psi_fluctuation_local[ion] += (Rho(i,j,k)*ElectricalPotential(i,j,k) - rho_psi_avg_global[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_mu_fluctuation_global[ion] =
rho_psi_fluctuation_global[ion]=Dm->Comm.sumReduce( rho_psi_fluctuation_local[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) { if (Dm->rank() == 0) {
@ -157,20 +184,28 @@ 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"); auto vis_db = input_db->getDatabase("Visualization");
char VisName[40]; char VisName[40];
std::vector<IO::MeshDataStruct> visData; 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("", "silo", "false");
// Create the MeshDataStruct // Create the MeshDataStruct
visData.resize(1); visData.resize(1);
visData[0].meshName = "domain"; 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 //electric potential
auto ElectricPotentialVar = std::make_shared<IO::Variable>(); auto ElectricPotentialVar = std::make_shared<IO::Variable>();
//electric field //electric field
@ -228,7 +263,8 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
IonConcentration[ion]->name = VisName; IonConcentration[ion]->name = VisName;
IonConcentration[ion]->type = IO::VariableType::VolumeVariable; IonConcentration[ion]->type = IO::VariableType::VolumeVariable;
IonConcentration[ion]->dim = 1; 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]); visData[0].vars.push_back(IonConcentration[ion]);
} }
} }
@ -256,23 +292,29 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
// x-component of diffusive flux // x-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxDiffusive_x", ion + 1); sprintf(VisName, "Ion%zu_FluxDiffusive_x", ion + 1);
IonFluxDiffusive[3 * ion + 0]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxDiffusive[3 * ion + 0]);
// y-component of diffusive flux // y-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxDiffusive_y", ion + 1); sprintf(VisName, "Ion%zu_FluxDiffusive_y", ion + 1);
IonFluxDiffusive[3 * ion + 1]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxDiffusive[3 * ion + 1]);
// z-component of diffusive flux // z-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxDiffusive_z", ion + 1); sprintf(VisName, "Ion%zu_FluxDiffusive_z", ion + 1);
IonFluxDiffusive[3 * ion + 2]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxDiffusive[3 * ion + 2]);
} }
} }
@ -282,23 +324,29 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
// x-component of advective flux // x-component of advective flux
sprintf(VisName, "Ion%zu_FluxAdvective_x", ion + 1); sprintf(VisName, "Ion%zu_FluxAdvective_x", ion + 1);
IonFluxAdvective[3 * ion + 0]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxAdvective[3 * ion + 0]);
// y-component of advective flux // y-component of advective flux
sprintf(VisName, "Ion%zu_FluxAdvective_y", ion + 1); sprintf(VisName, "Ion%zu_FluxAdvective_y", ion + 1);
IonFluxAdvective[3 * ion + 1]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxAdvective[3 * ion + 1]);
// z-component of advective flux // z-component of advective flux
sprintf(VisName, "Ion%zu_FluxAdvective_z", ion + 1); sprintf(VisName, "Ion%zu_FluxAdvective_z", ion + 1);
IonFluxAdvective[3 * ion + 2]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxAdvective[3 * ion + 2]);
} }
} }
@ -308,23 +356,29 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
// x-component of electro-migrational flux // x-component of electro-migrational flux
sprintf(VisName, "Ion%zu_FluxElectrical_x", ion + 1); sprintf(VisName, "Ion%zu_FluxElectrical_x", ion + 1);
IonFluxElectrical[3 * ion + 0]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxElectrical[3 * ion + 0]);
// y-component of electro-migrational flux // y-component of electro-migrational flux
sprintf(VisName, "Ion%zu_FluxElectrical_y", ion + 1); sprintf(VisName, "Ion%zu_FluxElectrical_y", ion + 1);
IonFluxElectrical[3 * ion + 1]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxElectrical[3 * ion + 1]);
// z-component of electro-migrational flux // z-component of electro-migrational flux
sprintf(VisName, "Ion%zu_FluxElectrical_z", ion + 1); sprintf(VisName, "Ion%zu_FluxElectrical_z", ion + 1);
IonFluxElectrical[3 * ion + 2]->name = VisName; 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]->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]); visData[0].vars.push_back(IonFluxElectrical[3 * ion + 2]);
} }
} }
@ -361,20 +415,27 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
sprintf(VisName, "IonConcentration_%zu", ion + 1); sprintf(VisName, "IonConcentration_%zu", ion + 1);
//IonConcentration[ion]->name = VisName; //IonConcentration[ion]->name = VisName;
ASSERT(visData[0].vars[1 + 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); Ion.getIonConcentration(Rho, ion);
fillData.copy(Rho, IonConcentrationData); fillData.copy(Rho, IonConcentrationData);
} }
} }
if (vis_db->getWithDefault<bool>("save_velocity", false)) { 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 + 0]->name ==
ASSERT(visData[0].vars[1+Ion.number_ion_species+1]->name=="Velocity_y"); "Velocity_x");
ASSERT(visData[0].vars[1+Ion.number_ion_species+2]->name=="Velocity_z"); 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); Stokes.getVelocity(Vel_x, Vel_y, Vel_z);
Array<double>& VelxData = visData[0].vars[1+Ion.number_ion_species+0]->data; Array<double> &VelxData =
Array<double>& VelyData = visData[0].vars[1+Ion.number_ion_species+1]->data; visData[0].vars[1 + Ion.number_ion_species + 0]->data;
Array<double>& VelzData = visData[0].vars[1+Ion.number_ion_species+2]->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_x, VelxData);
fillData.copy(Vel_y, VelyData); fillData.copy(Vel_y, VelyData);
fillData.copy(Vel_z, VelzData); fillData.copy(Vel_z, VelzData);
@ -386,20 +447,30 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
// x-component of diffusive flux // x-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxDiffusive_x", ion + 1); sprintf(VisName, "Ion%zu_FluxDiffusive_x", ion + 1);
//IonFluxDiffusive[3*ion+0]->name = VisName; //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 // y-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxDiffusive_y", ion + 1); sprintf(VisName, "Ion%zu_FluxDiffusive_y", ion + 1);
//IonFluxDiffusive[3*ion+1]->name = VisName; //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 // z-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxDiffusive_z", ion + 1); sprintf(VisName, "Ion%zu_FluxDiffusive_z", ion + 1);
//IonFluxDiffusive[3*ion+2]->name = VisName; //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_x =
Array<double>& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species+3*ion+1]->data; visData[0].vars[4 + Ion.number_ion_species + 3 * ion + 0]->data;
Array<double>& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species+3*ion+2]->data; Array<double> &IonFluxData_y =
Ion.getIonFluxDiffusive(IonFluxDiffusive_x,IonFluxDiffusive_y,IonFluxDiffusive_z,ion); 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_x, IonFluxData_x);
fillData.copy(IonFluxDiffusive_y, IonFluxData_y); fillData.copy(IonFluxDiffusive_y, IonFluxData_y);
fillData.copy(IonFluxDiffusive_z, IonFluxData_z); fillData.copy(IonFluxDiffusive_z, IonFluxData_z);
@ -412,20 +483,36 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
// x-component of diffusive flux // x-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxAdvective_x", ion + 1); sprintf(VisName, "Ion%zu_FluxAdvective_x", ion + 1);
//IonFluxDiffusive[3*ion+0]->name = VisName; //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 // y-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxAdvective_y", ion + 1); sprintf(VisName, "Ion%zu_FluxAdvective_y", ion + 1);
//IonFluxDiffusive[3*ion+1]->name = VisName; //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 // z-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxAdvective_z", ion + 1); sprintf(VisName, "Ion%zu_FluxAdvective_z", ion + 1);
//IonFluxDiffusive[3*ion+2]->name = VisName; //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_x =
Array<double>& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+1]->data; visData[0]
Array<double>& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species*(1+3)+3*ion+2]->data; .vars[4 + Ion.number_ion_species * (1 + 3) + 3 * ion + 0]
Ion.getIonFluxAdvective(IonFluxAdvective_x,IonFluxAdvective_y,IonFluxAdvective_z,ion); ->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_x, IonFluxData_x);
fillData.copy(IonFluxAdvective_y, IonFluxData_y); fillData.copy(IonFluxAdvective_y, IonFluxData_y);
fillData.copy(IonFluxAdvective_z, IonFluxData_z); fillData.copy(IonFluxAdvective_z, IonFluxData_z);
@ -438,20 +525,36 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
// x-component of diffusive flux // x-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxElectrical_x", ion + 1); sprintf(VisName, "Ion%zu_FluxElectrical_x", ion + 1);
//IonFluxDiffusive[3*ion+0]->name = VisName; //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 // y-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxElectrical_y", ion + 1); sprintf(VisName, "Ion%zu_FluxElectrical_y", ion + 1);
//IonFluxDiffusive[3*ion+1]->name = VisName; //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 // z-component of diffusive flux
sprintf(VisName, "Ion%zu_FluxElectrical_z", ion + 1); sprintf(VisName, "Ion%zu_FluxElectrical_z", ion + 1);
//IonFluxDiffusive[3*ion+2]->name = VisName; //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_x =
Array<double>& IonFluxData_y = visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+1]->data; visData[0]
Array<double>& IonFluxData_z = visData[0].vars[4+Ion.number_ion_species*(1+6)+3*ion+2]->data; .vars[4 + Ion.number_ion_species * (1 + 6) + 3 * ion + 0]
Ion.getIonFluxElectrical(IonFluxElectrical_x,IonFluxElectrical_y,IonFluxElectrical_z,ion); ->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_x, IonFluxData_x);
fillData.copy(IonFluxElectrical_y, IonFluxData_y); fillData.copy(IonFluxElectrical_y, IonFluxData_y);
fillData.copy(IonFluxElectrical_z, IonFluxData_z); fillData.copy(IonFluxElectrical_z, IonFluxData_z);
@ -459,13 +562,23 @@ void ElectroChemistryAnalyzer::WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &P
} }
if (vis_db->getWithDefault<bool>("save_electric_field", false)) { 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(
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+9)+1]->name=="ElectricField_y"); visData[0].vars[4 + Ion.number_ion_species * (1 + 9) + 0]->name ==
ASSERT(visData[0].vars[4+Ion.number_ion_species*(1+9)+2]->name=="ElectricField_z"); "ElectricField_x");
Poisson.getElectricField(ElectricalField_x, ElectricalField_y, ElectricalField_z); ASSERT(
Array<double>& ElectricalFieldxData = visData[0].vars[4+Ion.number_ion_species*(1+9)+0]->data; visData[0].vars[4 + Ion.number_ion_species * (1 + 9) + 1]->name ==
Array<double>& ElectricalFieldyData = visData[0].vars[4+Ion.number_ion_species*(1+9)+1]->data; "ElectricField_y");
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) + 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_x, ElectricalFieldxData);
fillData.copy(ElectricalField_y, ElectricalFieldyData); fillData.copy(ElectricalField_y, ElectricalFieldyData);
fillData.copy(ElectricalField_z, ElectricalFieldzData); fillData.copy(ElectricalField_z, ElectricalFieldzData);

View File

@ -57,11 +57,13 @@ public:
~ElectroChemistryAnalyzer(); ~ElectroChemistryAnalyzer();
void SetParams(); void SetParams();
void Basic( ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson, ScaLBL_StokesModel &Stokes, int timestep); void Basic(ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson,
void WriteVis( ScaLBL_IonModel &Ion, ScaLBL_Poisson &Poisson, ScaLBL_StokesModel &Stokes, std::shared_ptr<Database> input_db, int timestep); 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: private:
FILE *TIMELOG; FILE *TIMELOG;
}; };
#endif #endif

View File

@ -11,21 +11,26 @@ FlowAdaptor::FlowAdaptor(ScaLBL_ColorModel &M){
timestep = -1; timestep = -1;
timestep_previous = -1; timestep_previous = -1;
phi.resize(Nx,Ny,Nz); phi.fill(0); // phase indicator field phi.resize(Nx, Ny, Nz);
phi_t.resize(Nx,Ny,Nz); phi_t.fill(0); // time derivative for the phase indicator field 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(){ FlowAdaptor::~FlowAdaptor() {}
}
double FlowAdaptor::ImageInit(ScaLBL_ColorModel &M, std::string Filename) { double FlowAdaptor::ImageInit(ScaLBL_ColorModel &M, std::string Filename) {
int rank = M.rank; int rank = M.rank;
int Nx = M.Nx; int Ny = M.Ny; int Nz = M.Nz; int Nx = M.Nx;
if (rank==0) printf("Re-initializing fluids from file: %s \n", Filename.c_str()); 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); 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++)
for (int i=0; i<Nx*Ny*Nz; i++) M.Dm->id[i] = M.Mask->id[i]; // save what was read 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; double *PhaseLabel;
PhaseLabel = new double[Nx * Ny * Nz]; PhaseLabel = new double[Nx * Ny * Nz];
@ -39,8 +44,7 @@ double FlowAdaptor::ImageInit(ScaLBL_ColorModel &M, std::string Filename){
if (M.id[Nx * Ny * k + Nx * j + i] == 2) { if (M.id[Nx * Ny * k + Nx * j + i] == 2) {
PoreCount++; PoreCount++;
Count++; Count++;
} } else if (M.id[Nx * Ny * k + Nx * j + i] == 1) {
else if (M.id[Nx*Ny*k+Nx*j+i] == 1){
PoreCount++; PoreCount++;
} }
} }
@ -50,30 +54,37 @@ double FlowAdaptor::ImageInit(ScaLBL_ColorModel &M, std::string Filename){
Count = M.Dm->Comm.sumReduce(Count); Count = M.Dm->Comm.sumReduce(Count);
PoreCount = M.Dm->Comm.sumReduce(PoreCount); 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)); ScaLBL_CopyToDevice(M.Phi, PhaseLabel, Nx * Ny * Nz * sizeof(double));
M.Dm->Comm.barrier(); M.Dm->Comm.barrier();
ScaLBL_D3Q19_Init(M.fq, M.Np); 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, 0,
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, M.ScaLBL_Comm->FirstInterior(), M.ScaLBL_Comm->LastInterior(), M.Np); 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(); 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));
double saturation = Count / PoreCount; double saturation = Count / PoreCount;
return saturation; return saturation;
} }
double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M) { double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M) {
double MASS_FRACTION_CHANGE = 0.006; double MASS_FRACTION_CHANGE = 0.006;
double FRACTIONAL_FLOW_EPSILON = 5e-6; double FRACTIONAL_FLOW_EPSILON = 5e-6;
if (M.db->keyExists("FlowAdaptor")) { if (M.db->keyExists("FlowAdaptor")) {
auto flow_db = M.db->getDatabase("FlowAdaptor"); auto flow_db = M.db->getDatabase("FlowAdaptor");
MASS_FRACTION_CHANGE = flow_db->getWithDefault<double>( "mass_fraction_factor", 0.006); MASS_FRACTION_CHANGE =
FRACTIONAL_FLOW_EPSILON = flow_db->getWithDefault<double>( "fractional_flow_epsilon", 5e-6); 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; int Np = M.Np;
double dA, dB, phi; double dA, dB, phi;
@ -96,7 +107,9 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
ScaLBL_CopyToHost(Vel_y, &M.Velocity[Np], Np * sizeof(double)); ScaLBL_CopyToHost(Vel_y, &M.Velocity[Np], Np * sizeof(double));
ScaLBL_CopyToHost(Vel_z, &M.Velocity[2 * 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; mass_a = mass_b = 0.0;
double maxSpeed = 0.0; double maxSpeed = 0.0;
@ -110,8 +123,12 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
int n = M.Map(i, j, k); int n = M.Map(i, j, k);
//double distance = M.Averages->SDs(i,j,k); //double distance = M.Averages->SDs(i,j,k);
if (!(n < 0)) { 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]; dA = Aq_tmp[n] + Aq_tmp[n + Np] + Aq_tmp[n + 2 * 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]; 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); phi = (dA - dB) / (dA + dB);
Phase[n] = phi; Phase[n] = phi;
mass_a += dA; mass_a += dA;
@ -120,11 +137,11 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
vy = Vel_y[n]; vy = Vel_y[n];
vz = Vel_z[n]; vz = Vel_z[n];
double local_momentum = sqrt(vx * vx + vy * vy + vz * vz); 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) { if (phi > 0.0) {
sum_weights_A += local_weight * dA; sum_weights_A += local_weight * dA;
} } else {
else {
sum_weights_B += local_weight * dB; sum_weights_B += local_weight * dB;
} }
if (local_momentum > localMaxSpeed) { if (local_momentum > localMaxSpeed) {
@ -145,7 +162,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_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); //double total_momentum_B = sqrt(vbx_global*vbx_global+vby_global*vby_global+vbz_global*vbz_global);
/* compute the total mass change */ /* 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) if (fabs(TOTAL_MASS_CHANGE) > 0.1 * mass_a_global)
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) if (fabs(TOTAL_MASS_CHANGE) > 0.1 * mass_b_global)
@ -165,29 +183,42 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
vy = Vel_y[n]; vy = Vel_y[n];
vz = Vel_z[n]; vz = Vel_z[n];
double local_momentum = sqrt(vx * vx + vy * vy + vz * vz); 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 */ /* impose ceiling for spurious currents */
//if (local_momentum > maxSpeed) local_momentum = maxSpeed; //if (local_momentum > maxSpeed) local_momentum = maxSpeed;
if (phi > 0.0) { if (phi > 0.0) {
LOCAL_MASS_CHANGE = MASS_FACTOR_A * local_weight; LOCAL_MASS_CHANGE = MASS_FACTOR_A * local_weight;
Aq_tmp[n] -= 0.3333333333333333 * LOCAL_MASS_CHANGE; Aq_tmp[n] -= 0.3333333333333333 * LOCAL_MASS_CHANGE;
Aq_tmp[n+Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE; Aq_tmp[n + Np] -=
Aq_tmp[n+2*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE; 0.1111111111111111 * LOCAL_MASS_CHANGE;
Aq_tmp[n+3*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE; Aq_tmp[n + 2 * Np] -=
Aq_tmp[n+4*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE; 0.1111111111111111 * LOCAL_MASS_CHANGE;
Aq_tmp[n+5*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE; Aq_tmp[n + 3 * Np] -=
Aq_tmp[n+6*Np] -= 0.1111111111111111*LOCAL_MASS_CHANGE; 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; //DebugMassA[n] = (-1.0)*LOCAL_MASS_CHANGE;
} } else {
else{
LOCAL_MASS_CHANGE = MASS_FACTOR_B * local_weight; LOCAL_MASS_CHANGE = MASS_FACTOR_B * local_weight;
Bq_tmp[n] += 0.3333333333333333 * LOCAL_MASS_CHANGE; Bq_tmp[n] += 0.3333333333333333 * LOCAL_MASS_CHANGE;
Bq_tmp[n+Np] += 0.1111111111111111*LOCAL_MASS_CHANGE; Bq_tmp[n + Np] +=
Bq_tmp[n+2*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE; 0.1111111111111111 * LOCAL_MASS_CHANGE;
Bq_tmp[n+3*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE; Bq_tmp[n + 2 * Np] +=
Bq_tmp[n+4*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE; 0.1111111111111111 * LOCAL_MASS_CHANGE;
Bq_tmp[n+5*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE; Bq_tmp[n + 3 * Np] +=
Bq_tmp[n+6*Np] += 0.1111111111111111*LOCAL_MASS_CHANGE; 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; //DebugMassB[n] = LOCAL_MASS_CHANGE;
} }
} }
@ -195,7 +226,9 @@ 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 // Need to initialize Aq, Bq, Den, Phi directly
//ScaLBL_CopyToDevice(Phi,phase.data(),7*Np*sizeof(double)); //ScaLBL_CopyToDevice(Phi,phase.data(),7*Np*sizeof(double));
@ -208,14 +241,19 @@ double FlowAdaptor::UpdateFractionalFlow(ScaLBL_ColorModel &M){
void FlowAdaptor::Flatten(ScaLBL_ColorModel &M) { void FlowAdaptor::Flatten(ScaLBL_ColorModel &M) {
ScaLBL_D3Q19_Init(M.fq, M.Np); 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, 0,
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, M.ScaLBL_Comm->FirstInterior(), M.ScaLBL_Comm->LastInterior(), M.Np); 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 FlowAdaptor::MoveInterface(ScaLBL_ColorModel &M) {
double INTERFACE_CUTOFF = M.color_db->getWithDefault<double>( "move_interface_cutoff", 0.1 ); double INTERFACE_CUTOFF =
double MOVE_INTERFACE_FACTOR = M.color_db->getWithDefault<double>( "move_interface_factor", 10.0 ); 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)); ScaLBL_CopyToHost(phi.data(), M.Phi, Nx * Ny * Nz * sizeof(double));
/* compute the local derivative of phase indicator field */ /* compute the local derivative of phase indicator field */
@ -230,13 +268,16 @@ double FlowAdaptor::MoveInterface(ScaLBL_ColorModel &M){
double value2 = phi(n); double value2 = phi(n);
double dist2 = factor * log((1.0 + value2) / (1.0 - value2)); double dist2 = factor * log((1.0 + value2) / (1.0 - value2));
phi_t(n) = 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 */ /* time derivative of distance */
double dxdt = 0.125 * (dist2 - dist1); double dxdt = 0.125 * (dist2 - dist1);
/* extrapolate to move the distance further */ /* extrapolate to move the distance further */
double dist3 = dist2 + MOVE_INTERFACE_FACTOR * dxdt; double dist3 = dist2 + MOVE_INTERFACE_FACTOR * dxdt;
/* compute the new phase interface */ /* 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_displacement += fabs(MOVE_INTERFACE_FACTOR * dxdt);
total_interface_sites += 1.0; total_interface_sites += 1.0;
} }
@ -245,11 +286,14 @@ double FlowAdaptor::MoveInterface(ScaLBL_ColorModel &M){
return total_interface_sites; 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); const RankInfoStruct rank_info(M.rank, M.nprocx, M.nprocy, M.nprocz);
auto rank = M.rank; 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; auto N = Nx * Ny * Nz;
double vF = 0.f; double vF = 0.f;
double vS = 0.f; double vS = 0.f;
@ -258,10 +302,12 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
bool USE_CONNECTED_NWP = false; bool USE_CONNECTED_NWP = false;
DoubleArray phase(Nx, Ny, Nz); DoubleArray phase(Nx, Ny, Nz);
IntArray phase_label(Nx,Ny,Nz);; IntArray phase_label(Nx, Ny, Nz);
;
DoubleArray phase_distance(Nx, Ny, Nz); DoubleArray phase_distance(Nx, Ny, Nz);
Array<char> phase_id(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 // Basic algorithm to
// 1. Copy phase field to CPU // 1. Copy phase field to CPU
@ -271,7 +317,8 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
for (int k = 1; k < Nz - 1; k++) { for (int k = 1; k < Nz - 1; k++) {
for (int j = 1; j < Ny - 1; j++) { for (int j = 1; j < Ny - 1; j++) {
for (int i = 1; i < Nx - 1; i++) { 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 +334,8 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
double volume_connected = 0.0; double volume_connected = 0.0;
double second_biggest = 0.0; double second_biggest = 0.0;
if (USE_CONNECTED_NWP) { 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(); M.Dm->Comm.barrier();
// only operate on component "0"ScaLBL_ColorModel &M, // only operate on component "0"ScaLBL_ColorModel &M,
@ -300,8 +348,7 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
if (label == 0) { if (label == 0) {
phase_id(i, j, k) = 0; phase_id(i, j, k) = 0;
count += 1.0; count += 1.0;
} } else
else
phase_id(i, j, k) = 1; phase_id(i, j, k) = 1;
if (label == 1) { if (label == 1) {
second_biggest += 1.0; second_biggest += 1.0;
@ -311,8 +358,7 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
} }
volume_connected = M.Dm->Comm.sumReduce(count); volume_connected = M.Dm->Comm.sumReduce(count);
second_biggest = M.Dm->Comm.sumReduce(second_biggest); second_biggest = M.Dm->Comm.sumReduce(second_biggest);
} } else {
else {
// use the whole NWP // use the whole NWP
for (int k = 0; k < Nz; k++) { for (int k = 0; k < Nz; k++) {
for (int j = 0; j < Ny; j++) { for (int j = 0; j < Ny; j++) {
@ -320,12 +366,10 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
if (M.Averages->SDs(i, j, k) > 0.f) { if (M.Averages->SDs(i, j, k) > 0.f) {
if (phase(i, j, k) > 0.f) { if (phase(i, j, k) > 0.f) {
phase_id(i, j, k) = 0; phase_id(i, j, k) = 0;
} } else {
else {
phase_id(i, j, k) = 1; phase_id(i, j, k) = 1;
} }
} } else {
else {
phase_id(i, j, k) = 1; phase_id(i, j, k) = 1;
} }
} }
@ -343,8 +387,10 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
for (int i = 0; i < Nx; i++) { for (int i = 0; i < Nx; i++) {
if (phase_distance(i, j, k) < 3.f) { if (phase_distance(i, j, k) < 3.f) {
value = phase(i, j, k); value = phase(i, j, k);
if (value > 1.f) value=1.f; if (value > 1.f)
if (value < -1.f) 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 -- distance based on analytical form McClure, Prins et al, Comp. Phys. Comm.
temp = -factor * log((1.0 + value) / (1.0 - value)); temp = -factor * log((1.0 + value) / (1.0 - value));
/// use this approximation close to the object /// use this approximation close to the object
@ -358,21 +404,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",
if (rank==0) printf("MorphGrow with target volume fraction change %f \n", target_delta_volume/volume_initial); target_delta_volume / volume_initial);
double target_delta_volume_incremental = target_delta_volume; double target_delta_volume_incremental = target_delta_volume;
if (fabs(target_delta_volume) > 0.01 * volume_initial) 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 k = 0; k < Nz; k++) {
for (int j = 0; j < Ny; j++) { for (int j = 0; j < Ny; j++) {
for (int i = 0; i < Nx; i++) { for (int i = 0; i < Nx; i++) {
if (phase_distance(i,j,k) < 0.0 ) phase_id(i,j,k) = 0; if (phase_distance(i, j, k) < 0.0)
else phase_id(i,j,k) = 1; 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; //if (phase_distance(i,j,k) < 0.0 ) phase(i,j,k) = 1.0;
} }
} }
@ -388,7 +443,9 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
if (M.Averages->SDs(i, j, k) > 0.f) { if (M.Averages->SDs(i, j, k) > 0.f) {
if (d < 3.f) { if (d < 3.f) {
//phase(i,j,k) = -1.0; //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 +466,28 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
double volume_final = M.Dm->Comm.sumReduce(count); double volume_final = M.Dm->Comm.sumReduce(count);
delta_volume = (volume_final - volume_initial); 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)
if (rank == 0) printf(" new saturation = %f \n", volume_final/(M.Mask->Porosity()*double((Nx-2)*(Ny-2)*(Nz-2)*M.nprocs))); 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 // 6. copy back to the device
//if (rank==0) printf("MorphInit: copy data back to device\n"); //if (rank==0) printf("MorphInit: copy data back to device\n");
ScaLBL_CopyToDevice(M.Phi, phase.data(), N * sizeof(double)); ScaLBL_CopyToDevice(M.Phi, phase.data(), N * sizeof(double));
// 7. Re-initialize phase field and density // 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, 0,
ScaLBL_PhaseField_Init(M.dvcMap, M.Phi, M.Den, M.Aq, M.Bq, M.ScaLBL_Comm->FirstInterior(), M.ScaLBL_Comm->LastInterior(), M.Np); 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; 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) { 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, 0);
ScaLBL_SetSlice_z(M.Phi, 1.0, Nx, Ny, Nz, 1); ScaLBL_SetSlice_z(M.Phi, 1.0, Nx, Ny, Nz, 1);
@ -435,8 +502,8 @@ double FlowAdaptor::ShellAggregation(ScaLBL_ColorModel &M, const double target_d
return delta_volume; return delta_volume;
} }
double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M,
double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water_in_oil){ const double seed_water_in_oil) {
srand(time(NULL)); srand(time(NULL));
auto rank = M.rank; auto rank = M.rank;
auto Np = M.Np; auto Np = M.Np;
@ -450,11 +517,14 @@ double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water
ScaLBL_CopyToHost(Aq_tmp, M.Aq, 7 * Np * sizeof(double)); ScaLBL_CopyToHost(Aq_tmp, M.Aq, 7 * Np * sizeof(double));
ScaLBL_CopyToHost(Bq_tmp, M.Bq, 7 * Np * sizeof(double)); ScaLBL_CopyToHost(Bq_tmp, M.Bq, 7 * Np * sizeof(double));
for (int n = 0; n < M.ScaLBL_Comm->LastExterior(); n++) { for (int n = 0; n < M.ScaLBL_Comm->LastExterior(); n++) {
double random_value = seed_water_in_oil * double(rand()) / RAND_MAX; 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 dA = Aq_tmp[n] + Aq_tmp[n + Np] + Aq_tmp[n + 2 * 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]; 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); double phase_id = (dA - dB) / (dA + dB);
if (phase_id > 0.0) { if (phase_id > 0.0) {
Aq_tmp[n] -= 0.3333333333333333 * random_value; Aq_tmp[n] -= 0.3333333333333333 * random_value;
@ -476,10 +546,15 @@ double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water
mass_loss += random_value * seed_water_in_oil; 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 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 dA = Aq_tmp[n] + Aq_tmp[n + Np] + Aq_tmp[n + 2 * 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]; 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); double phase_id = (dA - dB) / (dA + dB);
if (phase_id > 0.0) { if (phase_id > 0.0) {
Aq_tmp[n] -= 0.3333333333333333 * random_value; Aq_tmp[n] -= 0.3333333333333333 * random_value;
@ -503,7 +578,8 @@ double FlowAdaptor::SeedPhaseField(ScaLBL_ColorModel &M, const double seed_water
count = M.Dm->Comm.sumReduce(count); count = M.Dm->Comm.sumReduce(count);
mass_loss = M.Dm->Comm.sumReduce(mass_loss); 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 // Need to initialize Aq, Bq, Den, Phi directly
//ScaLBL_CopyToDevice(Phi,phase.data(),7*Np*sizeof(double)); //ScaLBL_CopyToDevice(Phi,phase.data(),7*Np*sizeof(double));

View File

@ -12,7 +12,6 @@
#include "models/ColorModel.h" #include "models/ColorModel.h"
/** /**
* \class FlowAdaptor * \class FlowAdaptor
* @brief * @brief
@ -22,8 +21,6 @@
class FlowAdaptor { class FlowAdaptor {
public: public:
/** /**
* \brief Create a flow adaptor to operate on the LB model * \brief Create a flow adaptor to operate on the LB model
* @param M ScaLBL_ColorModel * @param M ScaLBL_ColorModel
@ -65,7 +62,8 @@ public:
* \details Update fractional flow condition. Mass will be preferentially added or removed from * \details Update fractional flow condition. Mass will be preferentially added or removed from
* phase regions based on where flow is occurring * phase regions based on where flow is occurring
* @param M ScaLBL_ColorModel * @param M ScaLBL_ColorModel
*/ double UpdateFractionalFlow(ScaLBL_ColorModel &M); */
double UpdateFractionalFlow(ScaLBL_ColorModel &M);
/** /**
* \brief image re-initialization * \brief image re-initialization
@ -82,6 +80,7 @@ public:
void Flatten(ScaLBL_ColorModel &M); void Flatten(ScaLBL_ColorModel &M);
DoubleArray phi; DoubleArray phi;
DoubleArray phi_t; DoubleArray phi_t;
private: private:
int Nx, Ny, Nz; int Nx, Ny, Nz;
int timestep; int timestep;

View File

@ -1,20 +1,29 @@
#include "analysis/FreeEnergy.h" #include "analysis/FreeEnergy.h"
FreeEnergyAnalyzer::FreeEnergyAnalyzer(std::shared_ptr <Domain> dm): FreeEnergyAnalyzer::FreeEnergyAnalyzer(std::shared_ptr<Domain> dm) : Dm(dm) {
Dm(dm)
{
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz; Nx = dm->Nx;
Volume=(Nx-2)*(Ny-2)*(Nz-2)*Dm->nprocx()*Dm->nprocy()*Dm->nprocz()*1.0; 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); ChemicalPotential.resize(Nx, Ny, Nz);
Phi.resize(Nx,Ny,Nz); Phi.fill(0); ChemicalPotential.fill(0);
Pressure.resize(Nx,Ny,Nz); Pressure.fill(0); Phi.resize(Nx, Ny, Nz);
Rho.resize(Nx,Ny,Nz); Rho.fill(0); Phi.fill(0);
Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field Pressure.resize(Nx, Ny, Nz);
Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0); Pressure.fill(0);
Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0); Rho.resize(Nx, Ny, Nz);
SDs.resize(Nx,Ny,Nz); SDs.fill(0); 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) { if (Dm->rank() == 0) {
bool WriteHeader = false; bool WriteHeader = false;
@ -25,14 +34,12 @@ FreeEnergyAnalyzer::FreeEnergyAnalyzer(std::shared_ptr <Domain> dm):
WriteHeader = true; WriteHeader = true;
TIMELOG = fopen("free.csv", "a+"); TIMELOG = fopen("free.csv", "a+");
if (WriteHeader) if (WriteHeader) {
{
// If timelog is empty, write a short header to list the averages // If timelog is empty, write a short header to list the averages
//fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n"); //fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n");
fprintf(TIMELOG, "timestep\n"); fprintf(TIMELOG, "timestep\n");
} }
} }
} }
FreeEnergyAnalyzer::~FreeEnergyAnalyzer() { FreeEnergyAnalyzer::~FreeEnergyAnalyzer() {
@ -41,9 +48,7 @@ FreeEnergyAnalyzer::~FreeEnergyAnalyzer(){
} }
} }
void FreeEnergyAnalyzer::SetParams(){ void FreeEnergyAnalyzer::SetParams() {}
}
void FreeEnergyAnalyzer::Basic(ScaLBL_FreeLeeModel &LeeModel, int timestep) { 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"); auto vis_db = input_db->getDatabase("Visualization");
std::vector<IO::MeshDataStruct> visData; 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("", "silo", "false");
// Create the MeshDataStruct // Create the MeshDataStruct
visData.resize(1); visData.resize(1);
visData[0].meshName = "domain"; 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 VisPhase = std::make_shared<IO::Variable>();
auto VisPressure = std::make_shared<IO::Variable>(); auto VisPressure = std::make_shared<IO::Variable>();
auto VisChemicalPotential = 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 VyVar = std::make_shared<IO::Variable>();
auto VzVar = std::make_shared<IO::Variable>(); auto VzVar = std::make_shared<IO::Variable>();
if (vis_db->getWithDefault<bool>("save_phase_field", true)) { if (vis_db->getWithDefault<bool>("save_phase_field", true)) {
VisPhase->name = "Phase"; VisPhase->name = "Phase";
VisPhase->type = IO::VariableType::VolumeVariable; VisPhase->type = IO::VariableType::VolumeVariable;

View File

@ -53,10 +53,10 @@ public:
void SetParams(); void SetParams();
void Basic(ScaLBL_FreeLeeModel &LeeModel, int timestep); 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: private:
FILE *TIMELOG; FILE *TIMELOG;
}; };
#endif #endif

View File

@ -1,25 +1,35 @@
#include "analysis/GreyPhase.h" #include "analysis/GreyPhase.h"
// Constructor // Constructor
GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr <Domain> dm): GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr<Domain> dm) : Dm(dm) {
Dm(dm) Nx = dm->Nx;
{ Ny = dm->Ny;
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz; Nz = dm->Nz;
Volume=(Nx-2)*(Ny-2)*(Nz-2)*Dm->nprocx()*Dm->nprocy()*Dm->nprocz()*1.0; Volume = (Nx - 2) * (Ny - 2) * (Nz - 2) * Dm->nprocx() * Dm->nprocy() *
Dm->nprocz() * 1.0;
// Global arrays // Global arrays
SDs.resize(Nx,Ny,Nz); SDs.fill(0); SDs.resize(Nx, Ny, Nz);
Porosity.resize(Nx,Ny,Nz); Porosity.fill(0); SDs.fill(0);
Porosity.resize(Nx, Ny, Nz);
Porosity.fill(0);
//PhaseID.resize(Nx,Ny,Nz); PhaseID.fill(0); //PhaseID.resize(Nx,Ny,Nz); PhaseID.fill(0);
Rho_n.resize(Nx,Ny,Nz); Rho_n.fill(0); Rho_n.resize(Nx, Ny, Nz);
Rho_w.resize(Nx,Ny,Nz); Rho_w.fill(0); Rho_n.fill(0);
Pressure.resize(Nx,Ny,Nz); Pressure.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); //Phi.resize(Nx,Ny,Nz); Phi.fill(0);
//DelPhi.resize(Nx,Ny,Nz); DelPhi.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_x.resize(Nx, Ny, Nz);
Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0); Vel_x.fill(0); // Gradient of the phase indicator field
Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0); Vel_y.resize(Nx, Ny, Nz);
MobilityRatio.resize(Nx,Ny,Nz); MobilityRatio.fill(0); 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) { if (Dm->rank() == 0) {
@ -31,8 +41,7 @@ GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr <Domain> dm):
WriteHeader = true; WriteHeader = true;
TIMELOG = fopen("timelog.csv", "a+"); TIMELOG = fopen("timelog.csv", "a+");
if (WriteHeader) if (WriteHeader) {
{
// If timelog is empty, write a short header to list the averages // If timelog is empty, write a short header to list the averages
//fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n"); //fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n");
fprintf(TIMELOG, "sw krw krn vw vn pw pn\n"); fprintf(TIMELOG, "sw krw krn vw vn pw pn\n");
@ -40,20 +49,15 @@ GreyPhaseAnalysis::GreyPhaseAnalysis(std::shared_ptr <Domain> dm):
} }
} }
// Destructor // 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; Fx = force_x;
Fy = force_y; Fy = force_y;
Fz = force_z; Fz = force_z;
@ -70,10 +74,13 @@ void GreyPhaseAnalysis::Basic(){
int i, j, k, n, imin, jmin, kmin, kmax; int i, j, k, n, imin, jmin, kmin, kmax;
// If external boundary conditions are set, do not average over the inlet // 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; imin = jmin = 1;
if (Dm->inlet_layers_z > 0 && Dm->kproc() == 0) kmin += Dm->inlet_layers_z; if (Dm->inlet_layers_z > 0 && Dm->kproc() == 0)
if (Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax -= Dm->outlet_layers_z; kmin += Dm->inlet_layers_z;
if (Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz() - 1)
kmax -= Dm->outlet_layers_z;
Water_local.reset(); Water_local.reset();
Oil_local.reset(); Oil_local.reset();
@ -93,21 +100,26 @@ void GreyPhaseAnalysis::Basic(){
double mobility_ratio = MobilityRatio(n); double mobility_ratio = MobilityRatio(n);
Water_local.M += nB * porosity; Water_local.M += nB * porosity;
Water_local.Px += porosity*(nA+nB)*Vel_x(n)*0.5*(1.0-mobility_ratio); Water_local.Px += porosity * (nA + nB) * Vel_x(n) * 0.5 *
Water_local.Py += porosity*(nA+nB)*Vel_y(n)*0.5*(1.0-mobility_ratio); (1.0 - mobility_ratio);
Water_local.Pz += porosity*(nA+nB)*Vel_z(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.M += nA * porosity;
Oil_local.Px += porosity*(nA+nB)*Vel_x(n)*0.5*(1.0+mobility_ratio); Oil_local.Px += porosity * (nA + nB) * Vel_x(n) * 0.5 *
Oil_local.Py += porosity*(nA+nB)*Vel_y(n)*0.5*(1.0+mobility_ratio); (1.0 + mobility_ratio);
Oil_local.Pz += porosity*(nA+nB)*Vel_z(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) { if (phi > 0.99) {
Oil_local.p += Pressure(n); Oil_local.p += Pressure(n);
//Oil_local.p += pressure*(rho_n*nA)/(rho_n*nA+rho_w*nB); //Oil_local.p += pressure*(rho_n*nA)/(rho_n*nA+rho_w*nB);
count_n += 1.0; count_n += 1.0;
} } else if (phi < -0.99) {
else if ( phi < -0.99 ){
Water_local.p += Pressure(n); Water_local.p += Pressure(n);
//Water_local.p += pressure*(rho_w*nB)/(rho_n*nA+rho_w*nB); //Water_local.p += pressure*(rho_w*nB)/(rho_n*nA+rho_w*nB);
count_w += 1.0; count_w += 1.0;
@ -126,7 +138,6 @@ void GreyPhaseAnalysis::Basic(){
Water.Py = Dm->Comm.sumReduce(Water_local.Py); Water.Py = Dm->Comm.sumReduce(Water_local.Py);
Water.Pz = Dm->Comm.sumReduce(Water_local.Pz); Water.Pz = Dm->Comm.sumReduce(Water_local.Pz);
//Oil.p /= Oil.M; //Oil.p /= Oil.M;
//Water.p /= Water.M; //Water.p /= Water.M;
count_w = Dm->Comm.sumReduce(count_w); count_w = Dm->Comm.sumReduce(count_w);
@ -142,17 +153,27 @@ void GreyPhaseAnalysis::Basic(){
// check for NaN // check for NaN
bool err = false; bool err = false;
if (Water.M != Water.M) err=true; if (Water.M != Water.M)
if (Water.p != Water.p) err=true; err = true;
if (Water.Px != Water.Px) err=true; if (Water.p != Water.p)
if (Water.Py != Water.Py) err=true; err = true;
if (Water.Pz != Water.Pz) 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.M != Oil.M)
if (Oil.p != Oil.p) err=true; err = true;
if (Oil.Px != Oil.Px) err=true; if (Oil.p != Oil.p)
if (Oil.Py != Oil.Py) err=true; err = true;
if (Oil.Pz != Oil.Pz) 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) { if (Dm->rank() == 0) {
double force_mag = sqrt(Fx * Fx + Fy * Fy + Fz * Fz); double force_mag = sqrt(Fx * Fx + Fy * Fy + Fz * Fz);
@ -163,14 +184,14 @@ void GreyPhaseAnalysis::Basic(){
dir_x = Fx / force_mag; dir_x = Fx / force_mag;
dir_y = Fy / force_mag; dir_y = Fy / force_mag;
dir_z = Fz / force_mag; dir_z = Fz / force_mag;
} } else {
else {
// default to z direction // default to z direction
dir_x = 0.0; dir_x = 0.0;
dir_y = 0.0; dir_y = 0.0;
dir_z = 1.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 // compute the pressure drop
double pressure_drop = (Pressure(Nx * Ny + Nx + 1) - 1.0) / 3.0; double pressure_drop = (Pressure(Nx * Ny + Nx + 1) - 1.0) / 3.0;
double length = ((Nz - 2) * Dm->nprocz()); double length = ((Nz - 2) * Dm->nprocz());
@ -184,21 +205,28 @@ void GreyPhaseAnalysis::Basic(){
force_mag = 1.0; force_mag = 1.0;
} }
saturation = Water.M / (Water.M + Oil.M); // assume constant density 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; water_flow_rate =
oil_flow_rate =grey_porosity*(1.0-saturation)*(Oil.Px*dir_x + Oil.Py*dir_y + Oil.Pz*dir_z)/Oil.M; 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; double h = Dm->voxel_length;
//TODO check if need greyporosity or domain porosity ? - compare to analytical solution //TODO check if need greyporosity or domain porosity ? - compare to analytical solution
double krn = h * h * nu_n * oil_flow_rate / force_mag; double krn = h * h * nu_n * oil_flow_rate / force_mag;
double krw = h * h * nu_w * water_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); //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); fflush(TIMELOG);
} }
if (err == true) { if (err == true) {
// exception if simulation produceds NaN // 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); ASSERT(err == false);
} }

View File

@ -15,7 +15,6 @@
#include "IO/Reader.h" #include "IO/Reader.h"
#include "IO/Writer.h" #include "IO/Writer.h"
/** /**
* \class GreyPhase * \class GreyPhase
* *
@ -27,14 +26,11 @@ class GreyPhase{
public: public:
double p; double p;
double M, Px, Py, Pz; double M, Px, Py, Pz;
void reset(){ void reset() { p = M = Px = Py = Pz = 0.0; }
p=M=Px=Py=Pz=0.0;
}
private: private:
}; };
/** /**
* \class GreyPhaseAnalysis * \class GreyPhaseAnalysis
* *
@ -76,7 +72,9 @@ public:
GreyPhaseAnalysis(std::shared_ptr<Domain> Dm); GreyPhaseAnalysis(std::shared_ptr<Domain> Dm);
~GreyPhaseAnalysis(); ~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 Basic();
void Write(int time); void Write(int time);
@ -85,4 +83,3 @@ private:
}; };
#endif #endif

View File

@ -29,25 +29,28 @@
#include <memory> #include <memory>
#define PI 3.14159265359 #define PI 3.14159265359
// Constructor // Constructor
Minkowski::Minkowski(std::shared_ptr <Domain> dm): Minkowski::Minkowski(std::shared_ptr<Domain> dm)
kstart(0), kfinish(0), isovalue(0), Volume(0), : kstart(0), kfinish(0), isovalue(0), Volume(0), LOGFILE(NULL), Dm(dm),
LOGFILE(NULL), Dm(dm), Vi(0), Vi_global(0) Vi(0), Vi_global(0) {
{ Nx = dm->Nx;
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz; Ny = dm->Ny;
Volume=double((Nx-2)*(Ny-2)*(Nz-2))*double(Dm->nprocx()*Dm->nprocy()*Dm->nprocz()); 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); id.resize(Nx, Ny, Nz);
label.resize(Nx,Ny,Nz); label.fill(0); id.fill(0);
distance.resize(Nx,Ny,Nz); distance.fill(0); label.resize(Nx, Ny, Nz);
label.fill(0);
distance.resize(Nx, Ny, Nz);
distance.fill(0);
if (Dm->rank() == 0) { if (Dm->rank() == 0) {
LOGFILE = fopen("minkowski.csv", "a+"); 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 // If LOGFILE is empty, write a short header to list the averages
//fprintf(LOGFILE,"--------------------------------------------------------------------------------------\n"); //fprintf(LOGFILE,"--------------------------------------------------------------------------------------\n");
fprintf(LOGFILE, "Vn An Jn Xn\n"); //miknowski measures, fprintf(LOGFILE, "Vn An Jn Xn\n"); //miknowski measures,
@ -55,15 +58,14 @@ Minkowski::Minkowski(std::shared_ptr <Domain> dm):
} }
} }
// Destructor // Destructor
Minkowski::~Minkowski() Minkowski::~Minkowski() {
{ if (LOGFILE != NULL) {
if ( LOGFILE!=NULL ) { fclose(LOGFILE); } fclose(LOGFILE);
}
} }
void Minkowski::ComputeScalar(const DoubleArray& Field, const double isovalue) void Minkowski::ComputeScalar(const DoubleArray &Field, const double isovalue) {
{
PROFILE_START("ComputeScalar"); PROFILE_START("ComputeScalar");
Xi = Ji = Ai = 0.0; Xi = Ji = Ai = 0.0;
DCEL object; DCEL object;
@ -149,7 +151,6 @@ void Minkowski::ComputeScalar(const DoubleArray& Field, const double isovalue)
PROFILE_STOP("ComputeScalar"); PROFILE_STOP("ComputeScalar");
} }
void Minkowski::MeasureObject() { void Minkowski::MeasureObject() {
/* /*
* compute the distance to an object * compute the distance to an object
@ -172,7 +173,6 @@ void Minkowski::MeasureObject(){
ComputeScalar(distance, 0.0); ComputeScalar(distance, 0.0);
} }
void Minkowski::MeasureObject(double factor, const DoubleArray &Phi) { void Minkowski::MeasureObject(double factor, const DoubleArray &Phi) {
/* /*
* compute the distance to an object * compute the distance to an object
@ -196,7 +196,8 @@ void Minkowski::MeasureObject(double factor, const DoubleArray &Phi){
double value = Phi(i, j, k); double value = Phi(i, j, k);
double dist_value = distance(i, j, k); double dist_value = distance(i, j, k);
if (dist_value < 2.5 && dist_value > -2.5) { 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) if (dist_value * new_distance < 0.0)
new_distance = (-1.0) * new_distance; new_distance = (-1.0) * new_distance;
distance(i, j, k) = new_distance; distance(i, j, k) = new_distance;
@ -206,10 +207,8 @@ void Minkowski::MeasureObject(double factor, const DoubleArray &Phi){
} }
ComputeScalar(distance, 0.0); ComputeScalar(distance, 0.0);
} }
int Minkowski::MeasureConnectedPathway() { int Minkowski::MeasureConnectedPathway() {
/* /*
* compute the connected pathway for object with LABEL in id field * compute the connected pathway for object with LABEL in id field
@ -225,8 +224,7 @@ int Minkowski::MeasureConnectedPathway(){
for (int i = 0; i < Nx; i++) { for (int i = 0; i < Nx; i++) {
if (id(i, j, k) == LABEL) { if (id(i, j, k) == LABEL) {
distance(i, j, k) = 1.0; distance(i, j, k) = 1.0;
} } else
else
distance(i, j, k) = -1.0; distance(i, j, k) = -1.0;
} }
} }
@ -234,7 +232,9 @@ int Minkowski::MeasureConnectedPathway(){
// Extract only the connected part of NWP // Extract only the connected part of NWP
double vF = 0.0; 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 ) // 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(); Dm->Comm.barrier();
@ -243,8 +243,7 @@ int Minkowski::MeasureConnectedPathway(){
for (int i = 0; i < Nx; i++) { for (int i = 0; i < Nx; i++) {
if (label(i, j, k) == 0) { if (label(i, j, k) == 0) {
id(i, j, k) = 0; id(i, j, k) = 0;
} } else {
else{
id(i, j, k) = 1; id(i, j, k) = 1;
} }
} }
@ -269,8 +268,7 @@ int Minkowski::MeasureConnectedPathway(double factor, const DoubleArray &Phi){
for (int i = 0; i < Nx; i++) { for (int i = 0; i < Nx; i++) {
if (id(i, j, k) == LABEL) { if (id(i, j, k) == LABEL) {
distance(i, j, k) = 1.0; distance(i, j, k) = 1.0;
} } else
else
distance(i, j, k) = -1.0; distance(i, j, k) = -1.0;
} }
} }
@ -278,18 +276,18 @@ int Minkowski::MeasureConnectedPathway(double factor, const DoubleArray &Phi){
// Extract only the connected part of NWP // Extract only the connected part of NWP
double vF = 0.0; 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 ) // 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(); Dm->Comm.barrier();
for (int k = 0; k < Nz; k++) { for (int k = 0; k < Nz; k++) {
for (int j = 0; j < Ny; j++) { for (int j = 0; j < Ny; j++) {
for (int i = 0; i < Nx; i++) { for (int i = 0; i < Nx; i++) {
if (label(i, j, k) == 0) { if (label(i, j, k) == 0) {
id(i, j, k) = 0; id(i, j, k) = 0;
} } else {
else{
id(i, j, k) = 1; id(i, j, k) = 1;
} }
} }
@ -299,12 +297,10 @@ int Minkowski::MeasureConnectedPathway(double factor, const DoubleArray &Phi){
return n_connected_components; return n_connected_components;
} }
void Minkowski::PrintAll() {
void Minkowski::PrintAll()
{
if (Dm->rank() == 0) { 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); fflush(LOGFILE);
} }
} }

View File

@ -42,7 +42,6 @@
* *
*/ */
class Minkowski { class Minkowski {
//........................................................................... //...........................................................................
int kstart, kfinish; int kstart, kfinish;
@ -70,18 +69,10 @@ public:
//........................................................................... //...........................................................................
int Nx, Ny, Nz; int Nx, Ny, Nz;
double V(){ double V() { return Vi; }
return Vi; double A() { return Ai; }
} double H() { return Ji; }
double A(){ double X() { return Xi; }
return Ai;
}
double H(){
return Ji;
}
double X(){
return Xi;
}
//.......................................................................... //..........................................................................
/** /**
@ -135,8 +126,6 @@ public:
* \brief print the scalar invariants * \brief print the scalar invariants
*/ */
void PrintAll(); void PrintAll();
}; };
#endif #endif

View File

@ -26,20 +26,44 @@ struct LBPM_Point {
}; };
typedef LBPM_Point 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) {
inline Point operator-(const Point &A,const Point &B) {return Point(A.x-B.x,A.y-B.y,A.z-B.z);} 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, const Point &B) {
inline Point operator/(const Point &A,double v) {return Point(A.x/v,A.y/v,A.z/v);} 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 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) {
inline bool operator!=(const Point &A,const Point &B) {return (A.x!=B.x || A.y!=B.y || A.z!=B.z);} 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 double Norm(const Point &A) {
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);} return sqrt(A.x * A.x + A.y * A.y + A.z * A.z);
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 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{ class PointList{
@ -104,25 +128,38 @@ PointList::~PointList()
delete data; delete data;
} }
*/ */
template <class T> template <class T> class DTList {
class DTList {
public: public:
DTList() : Data(0), length(0), refCount(new size_t(1)), outOfRange() {} 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);} DTList(const DTList<T> &A)
protected: : Data(A.Data), length(A.length), refCount(A.refCount), outOfRange() {
DTList(size_t len) : Data(len<=0 ? 0 : new T[len]), length(len<=0 ? 0 : len), refCount(new size_t(1)), outOfRange() {} ++(*refCount);
public: }
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() { virtual ~DTList() {
--(*refCount); --(*refCount);
if (*refCount==0) {delete [] Data; delete refCount;} if (*refCount == 0) {
Data = 0; refCount = 0; length=0; delete[] Data;
delete refCount;
}
Data = 0;
refCount = 0;
length = 0;
} }
DTList<T> &operator=(const DTList<T> &A) { DTList<T> &operator=(const DTList<T> &A) {
if (A.refCount != refCount) { // Otherwise doing A=A. if (A.refCount != refCount) { // Otherwise doing A=A.
--(*refCount); --(*refCount);
if (*refCount==0) {delete [] Data; delete refCount;} if (*refCount == 0) {
delete[] Data;
delete refCount;
}
refCount = A.refCount; refCount = A.refCount;
++(*refCount); ++(*refCount);
length = A.length; length = A.length;
@ -149,43 +186,50 @@ protected:
T outOfRange; T outOfRange;
}; };
template <class T> template <class T> class DTMutableList : public DTList<T> {
class DTMutableList : public DTList<T> {
public: public:
DTMutableList() : DTList<T>() {} DTMutableList() : DTList<T>() {}
DTMutableList(size_t len) : DTList<T>(len) {} DTMutableList(size_t len) : DTList<T>(len) {}
DTMutableList(const DTMutableList<T> &A) : DTList<T>(A) {} 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; } T *Pointer(void) { return DTList<T>::Data; }
const T *Pointer(void) const { 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) { return DTList<T>::Data[i]; }
T operator()(size_t i) const { 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) template <class T>
{ DTMutableList<T> TruncateSize(const DTList<T> &A, size_t length) {
if (length>A.Length()) length = A.Length(); if (length > A.Length())
length = A.Length();
DTMutableList<T> toReturn(length); DTMutableList<T> toReturn(length);
const T *fromP = A.Pointer(); const T *fromP = A.Pointer();
T *toP = toReturn.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; 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)); DTMutableList<T> toReturn(A.Length() + (addLength >= 0 ? addLength : 0));
size_t len = A.Length(); size_t len = A.Length();
const T *fromP = A.Pointer(); const T *fromP = A.Pointer();
T *toP = toReturn.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; return toReturn;
} }
#endif #endif

View File

@ -1,30 +1,44 @@
#include "analysis/SubPhase.h" #include "analysis/SubPhase.h"
// Constructor // Constructor
SubPhase::SubPhase(std::shared_ptr <Domain> dm): SubPhase::SubPhase(std::shared_ptr<Domain> dm) : Dm(dm) {
Dm(dm) Nx = dm->Nx;
{ Ny = dm->Ny;
Nx=dm->Nx; Ny=dm->Ny; Nz=dm->Nz; Nz = dm->Nz;
Volume=(Nx-2)*(Ny-2)*(Nz-2)*Dm->nprocx()*Dm->nprocy()*Dm->nprocz()*1.0; 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_w = std::shared_ptr<Minkowski>(new Minkowski(Dm));
morph_n = 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)); morph_i = std::shared_ptr<Minkowski>(new Minkowski(Dm));
// Global arrays // Global arrays
PhaseID.resize(Nx,Ny,Nz); PhaseID.fill(0); PhaseID.resize(Nx, Ny, Nz);
Label_WP.resize(Nx,Ny,Nz); Label_WP.fill(0); PhaseID.fill(0);
Label_NWP.resize(Nx,Ny,Nz); Label_NWP.fill(0); Label_WP.resize(Nx, Ny, Nz);
Rho_n.resize(Nx,Ny,Nz); Rho_n.fill(0); Label_WP.fill(0);
Rho_w.resize(Nx,Ny,Nz); Rho_w.fill(0); Label_NWP.resize(Nx, Ny, Nz);
Pressure.resize(Nx,Ny,Nz); Pressure.fill(0); Label_NWP.fill(0);
Phi.resize(Nx,Ny,Nz); Phi.fill(0); Rho_n.resize(Nx, Ny, Nz);
DelPhi.resize(Nx,Ny,Nz); DelPhi.fill(0); Rho_n.fill(0);
Vel_x.resize(Nx,Ny,Nz); Vel_x.fill(0); // Gradient of the phase indicator field Rho_w.resize(Nx, Ny, Nz);
Vel_y.resize(Nx,Ny,Nz); Vel_y.fill(0); Rho_w.fill(0);
Vel_z.resize(Nx,Ny,Nz); Vel_z.fill(0); Pressure.resize(Nx, Ny, Nz);
Dissipation.resize(Nx,Ny,Nz); Dissipation.fill(0); Pressure.fill(0);
SDs.resize(Nx,Ny,Nz); SDs.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; WriteHeader = true;
SUBPHASE = fopen("subphase.csv", "a+"); SUBPHASE = fopen("subphase.csv", "a+");
if (WriteHeader) if (WriteHeader) {
{
// If timelog is empty, write a short header to list the averages // 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, "time rn rw nun nuw Fx Fy Fz iftwn wet ");
fprintf(SUBPHASE, "pwc pwd pnc pnd "); // pressures fprintf(SUBPHASE, "pwc pwd pnc pnd "); // pressures
fprintf(SUBPHASE, "Mwc Mwd Mwi Mnc Mnd Mni Msw Msn "); // mass 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(
fprintf(SUBPHASE,"Pwc_y Pwd_y Pwi_y Pnc_y Pnd_y Pni_y Psw_y Psn_y "); SUBPHASE,
fprintf(SUBPHASE,"Pwc_z Pwd_z Pwi_z Pnc_z Pnd_z Pni_z Psw_z Psn_z "); "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, "Kwc Kwd Kwi Knc Knd Kni "); // kinetic energy
fprintf(SUBPHASE, "Dwc Dwd Dnc Dnd "); // viscous dissipation fprintf(SUBPHASE, "Dwc Dwd Dnc Dnd "); // viscous dissipation
fprintf(SUBPHASE, "Vwc Awc Hwc Xwc "); // wc region fprintf(SUBPHASE, "Vwc Awc Hwc Xwc "); // wc region
@ -59,18 +75,18 @@ SubPhase::SubPhase(std::shared_ptr <Domain> dm):
// stress tensor? // stress tensor?
} }
} } else {
else{
char LocalRankString[8]; char LocalRankString[8];
sprintf(LocalRankString, "%05d", Dm->rank()); sprintf(LocalRankString, "%05d", Dm->rank());
char LocalRankFilename[40]; char LocalRankFilename[40];
sprintf(LocalRankFilename, "%s%s", "subphase.csv.", LocalRankString); sprintf(LocalRankFilename, "%s%s", "subphase.csv.", LocalRankString);
SUBPHASE = fopen(LocalRankFilename, "a+"); SUBPHASE = fopen(LocalRankFilename, "a+");
//fprintf(SUBPHASE,"--------------------------------------------------------------------------------------\n");
fprintf(SUBPHASE, "time rn rw nun nuw Fx Fy Fz iftwn wet "); fprintf(SUBPHASE, "time rn rw nun nuw Fx Fy Fz iftwn wet ");
fprintf(SUBPHASE, "pwc pwd pnc pnd "); // pressures fprintf(SUBPHASE, "pwc pwd pnc pnd "); // pressures
fprintf(SUBPHASE, "Mwc Mwd Mwi Mnc Mnd Mni Msw Msn "); // mass 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_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_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, "Kwc Kwd Kwi Knc Knd Kni "); // kinetic energy
@ -92,63 +108,82 @@ SubPhase::SubPhase(std::shared_ptr <Domain> dm):
WriteHeader = true; WriteHeader = true;
TIMELOG = fopen("timelog.csv", "a+"); TIMELOG = fopen("timelog.csv", "a+");
if (WriteHeader) if (WriteHeader) {
{
// If timelog is empty, write a short header to list the averages // If timelog is empty, write a short header to list the averages
//fprintf(TIMELOG,"--------------------------------------------------------------------------------------\n"); fprintf(TIMELOG,
fprintf(TIMELOG,"sw krw krn krwf krnf vw vn force pw pn wet peff\n"); "sw krw krn krwf krnf vw vn force pw pn wet peff\n");
} }
} }
} }
// Destructor // Destructor
SubPhase::~SubPhase() SubPhase::~SubPhase() {
{ if (SUBPHASE != NULL) {
if ( SUBPHASE!=NULL ) { fclose(SUBPHASE); } fclose(SUBPHASE);
}
} }
void SubPhase::Write(int timestep) void SubPhase::Write(int timestep) {
{
if (Dm->rank() == 0) { 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 ", 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.M,
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); 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.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.Px,
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); gwd.Px, giwn.Pwx, gnc.Px, gnd.Px, giwn.Pnx, gifs.Pwx, gifs.Pnx);
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 %.8g %.8g %.8g %.8g ", gwc.Py,
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g ",gwc.visc, gwd.visc, gnc.visc, gnd.visc); 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 ", 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 ", 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 %i ", gnd.V, gnd.A, gnd.H, gnd.X,
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g ",giwn.V, giwn.A, giwn.H, giwn.X); gnd.Nc);
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g %i\n",giwnc.V, giwnc.A, giwnc.H, giwnc.X, giwnc.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); fflush(SUBPHASE);
} } else {
else{ fprintf(SUBPHASE, "%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g ",
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); 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 ", 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.M,
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); 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.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.Px,
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); wd.Px, iwn.Pwx, nc.Px, nd.Px, iwn.Pnx, ifs.Pwx, ifs.Pnx);
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 %.8g %.8g %.8g %.8g ", wc.Py,
fprintf(SUBPHASE,"%.8g %.8g %.8g %.8g ",wc.visc, wd.visc, nc.visc, nd.visc); 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 ", 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 ", 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 ", 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,
void SubPhase::SetParams(double rhoA, double rhoB, double tauA, double tauB, double force_x, double force_y, double force_z, double alpha, double B) double alpha, double B) {
{
Fx = force_x; Fx = force_x;
Fy = force_y; Fy = force_y;
Fz = force_z; Fz = force_z;
@ -164,15 +199,13 @@ void SubPhase::Basic(){
int i, j, k, n, imin, jmin, kmin, kmax; int i, j, k, n, imin, jmin, kmin, kmax;
// If external boundary conditions are set, do not average over the inlet // 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; imin = jmin = 1;
/*// If inlet/outlet layers exist use these as default
if (Dm->inlet_layers_x > 0) imin = Dm->inlet_layers_x; nb.reset();
if (Dm->inlet_layers_y > 0) jmin = Dm->inlet_layers_y; wb.reset();
if (Dm->inlet_layers_z > 0 && Dm->kproc() == 0) kmin += Dm->inlet_layers_z; iwn.reset();
if (Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax -= Dm->outlet_layers_z;
*/
nb.reset(); wb.reset(); iwn.reset();
double count_w = 0.0; double count_w = 0.0;
double count_n = 0.0; double count_n = 0.0;
@ -231,8 +264,7 @@ void SubPhase::Basic(){
nb.Px += rho_n * nA * Vel_x(n); nb.Px += rho_n * nA * Vel_x(n);
nb.Py += rho_n * nA * Vel_y(n); nb.Py += rho_n * nA * Vel_y(n);
nb.Pz += rho_n * nA * Vel_z(n); nb.Pz += rho_n * nA * Vel_z(n);
} } else {
else{
nB = 1.0; nB = 1.0;
wb.M += nB * rho_w; wb.M += nB * rho_w;
wb.V += 1.0; wb.V += 1.0;
@ -245,8 +277,7 @@ void SubPhase::Basic(){
if (phi > 0.99) { if (phi > 0.99) {
nb.p += Pressure(n); nb.p += Pressure(n);
count_n += 1.0; count_n += 1.0;
} } else if (phi < -0.99) {
else if ( phi < -0.99 ){
wb.p += Pressure(n); wb.p += Pressure(n);
count_w += 1.0; count_w += 1.0;
} }
@ -260,8 +291,7 @@ void SubPhase::Basic(){
iwn.Pnx += rho_n * nA * Vel_x(n); iwn.Pnx += rho_n * nA * Vel_x(n);
iwn.Pny += rho_n * nA * Vel_y(n); iwn.Pny += rho_n * nA * Vel_y(n);
iwn.Pnz += rho_n * nA * Vel_z(n); iwn.Pnz += rho_n * nA * Vel_z(n);
} } else {
else{
nB = 1.0; nB = 1.0;
iwn.Mw += nB * rho_w; iwn.Mw += nB * rho_w;
iwn.V += 1.0; 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); total_wetting_interaction_global =
count_wetting_interaction_global=Dm->Comm.sumReduce( count_wetting_interaction); Dm->Comm.sumReduce(total_wetting_interaction);
count_wetting_interaction_global =
Dm->Comm.sumReduce(count_wetting_interaction);
gwb.V = Dm->Comm.sumReduce(wb.V); gwb.V = Dm->Comm.sumReduce(wb.V);
gnb.V = Dm->Comm.sumReduce(nb.V); gnb.V = Dm->Comm.sumReduce(nb.V);
@ -328,16 +360,26 @@ void SubPhase::Basic(){
// check for NaN // check for NaN
bool err = false; bool err = false;
if (gwb.V != gwb.V) err=true; if (gwb.V != gwb.V)
if (gnb.V != gnb.V) err=true; err = true;
if (gwb.p != gwb.p) err=true; if (gnb.V != gnb.V)
if (gnb.p != gnb.p) err=true; err = true;
if (gwb.Px != gwb.Px) err=true; if (gwb.p != gwb.p)
if (gwb.Py != gwb.Py) err=true; err = true;
if (gwb.Pz != gwb.Pz) err=true; if (gnb.p != gnb.p)
if (gnb.Px != gnb.Px) err=true; err = true;
if (gnb.Py != gnb.Py) err=true; if (gwb.Px != gwb.Px)
if (gnb.Pz != gnb.Pz) err=true; 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) { if (Dm->rank() == 0) {
/* align flow direction based on total mass flux */ /* align flow direction based on total mass flux */
@ -350,13 +392,13 @@ void SubPhase::Basic(){
dir_x = Fx / force_mag; dir_x = Fx / force_mag;
dir_y = Fy / force_mag; dir_y = Fy / force_mag;
dir_z = Fz / force_mag; dir_z = Fz / force_mag;
} } else {
else {
dir_x /= flow_magnitude; dir_x /= flow_magnitude;
dir_y /= flow_magnitude; dir_y /= flow_magnitude;
dir_z /= 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 // compute the pressure drop
double pressure_drop = (Pressure(Nx * Ny + Nx + 1) - 1.0) / 3.0; double pressure_drop = (Pressure(Nx * Ny + Nx + 1) - 1.0) / 3.0;
double length = ((Nz - 2) * Dm->nprocz()); double length = ((Nz - 2) * Dm->nprocz());
@ -370,12 +412,20 @@ void SubPhase::Basic(){
force_mag = 1.0; force_mag = 1.0;
} }
double saturation = gwb.V / (gwb.V + gnb.V); 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 water_flow_rate =
double not_water_flow_rate=gnb.V*(gnb.Px*dir_x + gnb.Py*dir_y + gnb.Pz*dir_z)/gnb.M/ Dm->Volume; 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 */ /* 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 water_film_flow_rate =
double not_water_film_flow_rate=gnb.V*(giwn.Pnx*dir_x + giwn.Pny*dir_y + giwn.Pnz*dir_z)/gnb.M / Dm->Volume; 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 total_flow_rate = water_flow_rate + not_water_flow_rate;
//double fractional_flow = water_flow_rate / total_flow_rate; //double fractional_flow = water_flow_rate / total_flow_rate;
double h = Dm->voxel_length; double h = Dm->voxel_length;
@ -386,21 +436,25 @@ void SubPhase::Basic(){
double krwf = krw - h * h * nu_w * water_film_flow_rate / force_mag; double krwf = krw - h * h * nu_w * water_film_flow_rate / force_mag;
double eff_pressure = 1.0 / (krn + krw); // effective pressure drop 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", fprintf(TIMELOG,
"%.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g\n",
saturation, krw, krn, krwf, krnf, h * water_flow_rate, saturation, krw, krn, krwf, krnf, h * water_flow_rate,
h*not_water_flow_rate, force_mag, h * not_water_flow_rate, force_mag, gwb.p, gnb.p,
gwb.p, gnb.p, total_wetting_interaction_global, eff_pressure); total_wetting_interaction_global, eff_pressure);
fflush(TIMELOG); fflush(TIMELOG);
} }
if (err == true) { if (err == true) {
// exception if simulation produceds NaN // 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); ASSERT(err == false);
} }
inline void InterfaceTransportMeasures( double beta, double rA, double rB, double nA, double nB, inline void InterfaceTransportMeasures(double beta, double rA, double rB,
double nx, double ny, double nz, double ux, double uy, double uz, interface &I){ 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 A1, A2, A3, A4, A5, A6;
double B1, B2, B3, B4, B5, B6; double B1, B2, B3, B4, B5, B6;
@ -413,7 +467,8 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
// q = 0,2,4 // q = 0,2,4
// Cq = {1,0,0}, {0,1,0}, {0,0,1} // Cq = {1,0,0}, {0,1,0}, {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nx; 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; A1 = nA * (0.1111111111111111 * (1 + 4.5 * ux)) + delta;
B1 = nB * (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; A2 = nA * (0.1111111111111111 * (1 - 4.5 * ux)) - delta;
@ -422,7 +477,8 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
//............................................... //...............................................
// Cq = {0,1,0} // Cq = {0,1,0}
delta = beta * nA * nB * nAB * 0.1111111111111111 * ny; 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; A3 = nA * (0.1111111111111111 * (1 + 4.5 * uy)) + delta;
B3 = nB * (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; A4 = nA * (0.1111111111111111 * (1 - 4.5 * uy)) - delta;
@ -432,7 +488,8 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
// q = 4 // q = 4
// Cq = {0,0,1} // Cq = {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nz; 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; A5 = nA * (0.1111111111111111 * (1 + 4.5 * uz)) + delta;
B5 = nB * (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; A6 = nA * (0.1111111111111111 * (1 - 4.5 * uz)) - delta;
@ -461,8 +518,7 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
I.Pnx += rA * ux; I.Pnx += rA * ux;
I.Pny += rA * uy; I.Pny += rA * uy;
I.Pnz += rA * uz; I.Pnz += rA * uz;
} } else {
else {
I.Mw += rB; I.Mw += rB;
I.Pwx += rB * ux; I.Pwx += rB * ux;
I.Pwy += rB * uy; I.Pwy += rB * uy;
@ -470,26 +526,23 @@ inline void InterfaceTransportMeasures( double beta, double rA, double rB, doubl
} }
I.Kn += rA * nA * (unx * unx + uny * uny + unz * unz); I.Kn += rA * nA * (unx * unx + uny * uny + unz * unz);
I.Kw += rB * nB * (uwx * uwx + uwy * uwy + uwz * uwz); I.Kw += rB * nB * (uwx * uwx + uwy * uwy + uwz * uwz);
} }
void SubPhase::Full() { void SubPhase::Full() {
int i, j, k, n, imin, jmin, kmin, kmax; int i, j, k, n, imin, jmin, kmin, kmax;
// If external boundary conditions are set, do not average over the inlet // If external boundary conditions are set, do not average over the inlet
kmin=1; kmax=Nz-1; kmin = 1;
/*if (Dm->BoundaryCondition > 0 && Dm->BoundaryCondition != 5 && Dm->kproc() == 0) kmin=4; kmax = Nz - 1;
if (Dm->BoundaryCondition > 0 && Dm->BoundaryCondition != 5 && Dm->kproc() == Dm->nprocz()-1) kmax=Nz-4;
*/
imin = jmin = 1; imin = jmin = 1;
/*// If inlet layers exist use these as default
* NOTE -- excluding inlet / outlet will screw up topological averages!!! nd.reset();
if (Dm->inlet_layers_x > 0) imin = Dm->inlet_layers_x; nc.reset();
if (Dm->inlet_layers_y > 0) jmin = Dm->inlet_layers_y; wd.reset();
if (Dm->inlet_layers_z > 0 && Dm->kproc() == 0) kmin += Dm->inlet_layers_z; wc.reset();
if (Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax -= Dm->outlet_layers_z; iwn.reset();
*/ iwnc.reset();
nd.reset(); nc.reset(); wd.reset(); wc.reset(); iwn.reset(); iwnc.reset(); ifs.reset(); ifs.reset();
Dm->CommunicateMeshHalo(Phi); Dm->CommunicateMeshHalo(Phi);
for (int k = 1; k < Nz - 1; k++) { for (int k = 1; k < Nz - 1; k++) {
@ -505,7 +558,6 @@ void SubPhase::Full(){
} }
Dm->CommunicateMeshHalo(DelPhi); Dm->CommunicateMeshHalo(DelPhi);
Dm->CommunicateMeshHalo(Vel_x); Dm->CommunicateMeshHalo(Vel_x);
Dm->CommunicateMeshHalo(Vel_y); Dm->CommunicateMeshHalo(Vel_y);
Dm->CommunicateMeshHalo(Vel_z); Dm->CommunicateMeshHalo(Vel_z);
@ -526,7 +578,11 @@ void SubPhase::Full(){
double wy = 0.5 * (Vel_z(i, j + 1, k) - Vel_z(i, j - 1, k)); 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)); double wz = 0.5 * (Vel_z(i, j, k + 1) - Vel_z(i, j, k - 1));
if (SDs(i, j, k) > 2.0) { 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));
} }
} }
} }
@ -543,12 +599,10 @@ void SubPhase::Full(){
// Solid phase // Solid phase
morph_n->id(i, j, k) = 1; morph_n->id(i, j, k) = 1;
} } else if (Phi(n) > 0.0) {
else if (Phi(n) > 0.0){
// non-wetting phase // non-wetting phase
morph_n->id(i, j, k) = 0; morph_n->id(i, j, k) = 0;
} } else {
else {
// wetting phase // wetting phase
morph_n->id(i, j, k) = 1; morph_n->id(i, j, k) = 1;
} }
@ -592,12 +646,10 @@ void SubPhase::Full(){
// Solid phase // Solid phase
morph_w->id(i, j, k) = 1; morph_w->id(i, j, k) = 1;
} } else if (Phi(n) < 0.0) {
else if (Phi(n) < 0.0){
// wetting phase // wetting phase
morph_w->id(i, j, k) = 0; morph_w->id(i, j, k) = 0;
} } else {
else {
// non-wetting phase // non-wetting phase
morph_w->id(i, j, k) = 1; morph_w->id(i, j, k) = 1;
} }
@ -639,12 +691,10 @@ void SubPhase::Full(){
if (!(Dm->id[n] > 0)) { if (!(Dm->id[n] > 0)) {
// Solid phase // Solid phase
morph_i->id(i, j, k) = 1; morph_i->id(i, j, k) = 1;
} } else if (DelPhi(n) > 1e-4) {
else if (DelPhi(n) > 1e-4){
// interface // interface
morph_i->id(i, j, k) = 0; morph_i->id(i, j, k) = 0;
} } else {
else {
// not interface // not interface
morph_i->id(i, j, k) = 1; morph_i->id(i, j, k) = 1;
} }
@ -698,9 +748,10 @@ void SubPhase::Full(){
double nz = 0.5 * (Phi(i, j, k + 1) - Phi(i, j, k - 1)); double nz = 0.5 * (Phi(i, j, k + 1) - Phi(i, j, k - 1));
if (SDs(n) > 2.5) { if (SDs(n) > 2.5) {
// not a film region // not a film region
InterfaceTransportMeasures( beta, rho_w, rho_n, nA, nB, nx, ny, nz, ux, uy, uz, iwn); InterfaceTransportMeasures(beta, rho_w, rho_n, nA,
} nB, nx, ny, nz, ux, uy,
else{ uz, iwn);
} else {
// films that are close to the wetting fluid // films that are close to the wetting fluid
if (morph_w->distance(i, j, k) < 2.5 && phi > 0.0) { if (morph_w->distance(i, j, k) < 2.5 && phi > 0.0) {
ifs.Mw += rho_w; ifs.Mw += rho_w;
@ -716,24 +767,20 @@ void SubPhase::Full(){
ifs.Pnz += rho_n * uz; ifs.Pnz += rho_n * uz;
} }
} }
} } else if (phi > 0.0) {
else if ( phi > 0.0){
if (morph_n->label(i, j, k) > 0) { if (morph_n->label(i, j, k) > 0) {
vol_nd_bulk += 1.0; vol_nd_bulk += 1.0;
nd.p += Pressure(n); nd.p += Pressure(n);
} } else {
else{
vol_nc_bulk += 1.0; vol_nc_bulk += 1.0;
nc.p += Pressure(n); nc.p += Pressure(n);
} }
} } else {
else{
// water region // water region
if (morph_w->label(i, j, k) > 0) { if (morph_w->label(i, j, k) > 0) {
vol_wd_bulk += 1.0; vol_wd_bulk += 1.0;
wd.p += Pressure(n); wd.p += Pressure(n);
} } else {
else{
vol_wc_bulk += 1.0; vol_wc_bulk += 1.0;
wc.p += Pressure(n); wc.p += Pressure(n);
} }
@ -747,8 +794,7 @@ void SubPhase::Full(){
nd.Pz += nA * rho_n * uz; nd.Pz += nA * rho_n * uz;
nd.K += nA * rho_n * (ux * ux + uy * uy + uz * uz); nd.K += nA * rho_n * (ux * ux + uy * uy + uz * uz);
nd.visc += visc; nd.visc += visc;
} } else {
else{
nA = 1.0; nA = 1.0;
nc.M += nA * rho_n; nc.M += nA * rho_n;
nc.Px += nA * rho_n * ux; nc.Px += nA * rho_n * ux;
@ -757,8 +803,7 @@ void SubPhase::Full(){
nc.K += nA * rho_n * (ux * ux + uy * uy + uz * uz); nc.K += nA * rho_n * (ux * ux + uy * uy + uz * uz);
nc.visc += visc; nc.visc += visc;
} }
} } else {
else{
// water region // water region
if (morph_w->label(i, j, k) > 0) { if (morph_w->label(i, j, k) > 0) {
nB = 1.0; nB = 1.0;
@ -768,8 +813,7 @@ void SubPhase::Full(){
wd.Pz += nB * rho_w * uz; wd.Pz += nB * rho_w * uz;
wd.K += nB * rho_w * (ux * ux + uy * uy + uz * uz); wd.K += nB * rho_w * (ux * ux + uy * uy + uz * uz);
wd.visc += visc; wd.visc += visc;
} } else {
else{
nB = 1.0; nB = 1.0;
wc.M += nB * rho_w; wc.M += nB * rho_w;
wc.Px += nB * rho_w * ux; wc.Px += nB * rho_w * ux;
@ -862,15 +906,12 @@ void SubPhase::Full(){
gnd.p = gnd.p / vol_nd_bulk; 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 nx = Dm->Nx;
int ny = Dm->Ny; int ny = Dm->Ny;
int nz = Dm->Nz; 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 // assign the ID from the phase indicator field
for (int k = 0; k < nz; k++) { for (int k = 0; k < nz; k++) {
for (int j = 0; j < ny; j++) { for (int j = 0; j < ny; j++) {
@ -879,8 +920,10 @@ void SubPhase::AggregateLabels( const std::string& filename )
signed char local_id_val = Dm->id[n]; signed char local_id_val = Dm->id[n];
if (local_id_val > 0) { if (local_id_val > 0) {
double value = Phi(i, j, k); double value = Phi(i, j, k);
if (value > 0.0) local_id_val = 1; if (value > 0.0)
else local_id_val = 2; local_id_val = 1;
else
local_id_val = 2;
} }
Dm->id[n] = local_id_val; Dm->id[n] = local_id_val;
} }
@ -889,8 +932,4 @@ void SubPhase::AggregateLabels( const std::string& filename )
Dm->Comm.barrier(); Dm->Comm.barrier();
Dm->AggregateLabels(filename); Dm->AggregateLabels(filename);
} }

View File

@ -17,7 +17,6 @@
#include "IO/Reader.h" #include "IO/Reader.h"
#include "IO/Writer.h" #include "IO/Writer.h"
class phase { class phase {
public: public:
int Nc; int Nc;
@ -86,7 +85,8 @@ public:
IntArray PhaseID; // Phase ID array (solid=0, non-wetting=1, wetting=2) IntArray PhaseID; // Phase ID array (solid=0, non-wetting=1, wetting=2)
BlobIDArray Label_WP; // Wetting phase label BlobIDArray Label_WP; // Wetting phase label
BlobIDArray Label_NWP; // Non-wetting phase label index (0:nblobs-1) 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_n; // density field
DoubleArray Rho_w; // density field DoubleArray Rho_w; // density field
DoubleArray Phi; // phase indicator field DoubleArray Phi; // phase indicator field
@ -105,7 +105,9 @@ public:
SubPhase(std::shared_ptr<Domain> Dm); SubPhase(std::shared_ptr<Domain> Dm);
~SubPhase(); ~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 Basic();
void Full(); void Full();
void Write(int time); void Write(int time);
@ -117,4 +119,3 @@ private:
}; };
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -33,11 +33,11 @@
#include "IO/Reader.h" #include "IO/Reader.h"
#include "IO/Writer.h" #include "IO/Writer.h"
class TwoPhase { 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 n_nw_tris, n_ns_tris, n_ws_tris, n_nws_seg, n_local_sol_tris;
//........................................................................... //...........................................................................
int nc; int nc;
@ -97,7 +97,8 @@ public:
double pan, paw; // local phase averaged pressure double pan, paw; // local phase averaged pressure
// Global averages (all processes) // Global averages (all processes)
double pan_global, paw_global; // local phase averaged pressure 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 awn_global, ans_global, aws_global;
double lwns_global; double lwns_global;
double efawns, efawns_global; // averaged contact angle double efawns, efawns_global; // averaged contact angle
@ -143,7 +144,8 @@ public:
IntArray PhaseID; // Phase ID array (solid=0, non-wetting=1, wetting=2) IntArray PhaseID; // Phase ID array (solid=0, non-wetting=1, wetting=2)
BlobIDArray Label_WP; // Wetting phase label BlobIDArray Label_WP; // Wetting phase label
BlobIDArray Label_NWP; // Non-wetting phase label index (0:nblobs-1) 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 SDn;
DoubleArray SDs; DoubleArray SDs;
DoubleArray Phase; DoubleArray Phase;
@ -179,7 +181,8 @@ public:
void UpdateMeshValues(); void UpdateMeshValues();
void UpdateSolid(); void UpdateSolid();
void ComputeDelPhi(); void ComputeDelPhi();
void ColorToSignedDistance(double Beta, DoubleArray &ColorData, DoubleArray &DistData); void ColorToSignedDistance(double Beta, DoubleArray &ColorData,
DoubleArray &DistData);
void ComputeLocal(); void ComputeLocal();
void AssignComponentLabels(); void AssignComponentLabels();
void ComponentAverages(); void ComponentAverages();
@ -189,15 +192,11 @@ public:
int GetCubeLabel(int i, int j, int k, IntArray &BlobLabel); int GetCubeLabel(int i, int j, int k, IntArray &BlobLabel);
void SortBlobs(); void SortBlobs();
void PrintComponents(int timestep); 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); void SetParams(double rhoA, double rhoB, double tauA, double tauB,
double Volume_w(){ double force_x, double force_y, double force_z,
return wp_volume_global; double alpha);
} double Volume_w() { return wp_volume_global; }
double Volume_n(){ double Volume_n() { return nwp_volume_global; }
return nwp_volume_global;
}
}; };
#endif #endif

View File

@ -14,24 +14,25 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "analysis/analysis.h" #include "analysis/analysis.h"
#include "ProfilerApp.h" #include "ProfilerApp.h"
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
template <class TYPE> inline TYPE *getPtr(std::vector<TYPE> &x) {
template<class TYPE> return x.empty() ? NULL : &x[0];
inline TYPE* getPtr( std::vector<TYPE>& x ) { return x.empty() ? NULL:&x[0]; } }
template<class TYPE> template <class TYPE> inline const TYPE *getPtr(const std::vector<TYPE> &x) {
inline const TYPE* getPtr( const std::vector<TYPE>& x ) { return x.empty() ? NULL:&x[0]; } return x.empty() ? NULL : &x[0];
}
/****************************************************************** /******************************************************************
* Compute the blobs * * 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); PROFILE_START("ComputeBlob", 1);
ASSERT(isPhase.size() == LocalBlobID.size()); ASSERT(isPhase.size() == LocalBlobID.size());
const int Nx = isPhase.size(0); // maxima for the meshes const int Nx = isPhase.size(0); // maxima for the meshes
@ -42,27 +43,33 @@ int ComputeBlob( const Array<bool>& isPhase, BlobIDArray& LocalBlobID, bool peri
// Get the list of neighbors we need to check // Get the list of neighbors we need to check
int N_neighbors = 0; int N_neighbors = 0;
int d[26][3]; 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) { if (include_corners) {
// Include corners/edges as neighbors, check all cells // Include corners/edges as neighbors, check all cells
N_neighbors = 26; 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}, const int tmp[26][3] = {
{1,1,0},{1,-1,0},{-1,1,0},{-1,-1,0},{1,0,1},{-1,0,1}, {1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1},
{1,0,-1},{-1,0,-1},{0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, {0, 0, -1}, {1, 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, 0, 1}, {-1, 0, 1}, {1, 0, -1}, {-1, 0, -1}, {0, 1, 1},
{-1,-1,1},{-1,-1,-1}}; // directions to neighbors {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)); memcpy(d, tmp, sizeof(tmp));
} else { } else {
// Do not include corners/edges as neighbors // Do not include corners/edges as neighbors
if (periodic) { if (periodic) {
// Include all neighbors for periodic problems // Include all neighbors for periodic problems
N_neighbors = 6; 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)); memcpy(d, tmp, sizeof(tmp));
} else { } else {
// We only need to include the lower neighbors for non-periodic problems // We only need to include the lower neighbors for non-periodic problems
N_neighbors = 3; 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)); memcpy(d, tmp, sizeof(tmp));
} }
} }
@ -93,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 < 0 ? Nz - 1 : z2; // Periodic BC for x
z2 = z2 > Nz - 1 ? 0 : z2; z2 = z2 > Nz - 1 ? 0 : z2;
} else { } 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; continue;
} }
// Check if a neighbor has a known blob id // Check if a neighbor has a known blob id
@ -119,7 +127,8 @@ int ComputeBlob( const Array<bool>& isPhase, BlobIDArray& LocalBlobID, bool peri
id = std::min(id, neighbor_ids[i]); id = std::min(id, neighbor_ids[i]);
LocalBlobIDPtr[index] = id; LocalBlobIDPtr[index] = id;
for (int i = 0; i < N_list; i++) 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);
} }
} }
} }
@ -144,13 +153,12 @@ int ComputeBlob( const Array<bool>& isPhase, BlobIDArray& LocalBlobID, bool peri
return last - start_id + 1; return last - start_id + 1;
} }
/****************************************************************** /******************************************************************
* Compute the local blob ids * * Compute the local blob ids *
******************************************************************/ ******************************************************************/
int ComputeLocalBlobIDs(const DoubleArray &Phase, const DoubleArray &SignDist, 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"); PROFILE_START("ComputeLocalBlobIDs");
ASSERT(SignDist.size() == Phase.size()); ASSERT(SignDist.size() == Phase.size());
size_t Nx = Phase.size(0); size_t Nx = Phase.size(0);
@ -176,8 +184,8 @@ int ComputeLocalBlobIDs( const DoubleArray& Phase, const DoubleArray& SignDist,
PROFILE_STOP("ComputeLocalBlobIDs"); PROFILE_STOP("ComputeLocalBlobIDs");
return nblobs; 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"); PROFILE_START("ComputeLocalPhaseComponent");
size_t Nx = PhaseID.size(0); size_t Nx = PhaseID.size(0);
size_t Ny = PhaseID.size(1); size_t Ny = PhaseID.size(1);
@ -200,12 +208,11 @@ int ComputeLocalPhaseComponent(const IntArray &PhaseID, int &VALUE, BlobIDArray
return ncomponents; return ncomponents;
} }
/****************************************************************** /******************************************************************
* Reorder the global blob ids * * 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) if (N_blobs == 0)
return 0; return 0;
PROFILE_START("ReorderBlobIDs2", 1); PROFILE_START("ReorderBlobIDs2", 1);
@ -251,8 +258,7 @@ static int ReorderBlobIDs2( BlobIDArray& ID, int N_blobs, int ngx, int ngy, int
PROFILE_STOP("ReorderBlobIDs2", 1); PROFILE_STOP("ReorderBlobIDs2", 1);
return N_blobs2; return N_blobs2;
} }
void ReorderBlobIDs( BlobIDArray& ID, const Utilities::MPI& comm ) void ReorderBlobIDs(BlobIDArray &ID, const Utilities::MPI &comm) {
{
PROFILE_START("ReorderBlobIDs"); PROFILE_START("ReorderBlobIDs");
int tmp = ID.max() + 1; int tmp = ID.max() + 1;
int N_blobs = 0; int N_blobs = 0;
@ -261,7 +267,6 @@ void ReorderBlobIDs( BlobIDArray& ID, const Utilities::MPI& comm )
PROFILE_STOP("ReorderBlobIDs"); PROFILE_STOP("ReorderBlobIDs");
} }
/****************************************************************** /******************************************************************
* Compute the global blob ids * * Compute the global blob ids *
******************************************************************/ ******************************************************************/
@ -270,14 +275,12 @@ struct global_id_info_struct {
std::set<int64_t> remote_ids; std::set<int64_t> remote_ids;
}; };
// Send the local ids and their new value to all neighbors // Send the local ids and their new value to all neighbors
static void updateRemoteIds( static void updateRemoteIds(const std::map<int64_t, global_id_info_struct> &map,
const std::map<int64_t,global_id_info_struct>& map, const std::vector<int> &neighbors, int N_send,
const std::vector<int>& neighbors, const std::vector<int> &N_recv, int64_t *send_buf,
int N_send, const std::vector<int>& N_recv, std::vector<int64_t *> &recv_buf,
int64_t *send_buf, std::vector<int64_t*>& recv_buf,
std::map<int64_t, int64_t> &remote_map, 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> send_req(neighbors.size());
std::vector<MPI_Request> recv_req(neighbors.size()); std::vector<MPI_Request> recv_req(neighbors.size());
auto it = map.begin(); auto it = map.begin();
@ -302,14 +305,14 @@ static void updateRemoteIds(
} }
// Compute a new local id for each local id // Compute a new local id for each local id
static bool updateLocalIds(const std::map<int64_t, int64_t> &remote_map, 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; bool changed = false;
std::map<int64_t, global_id_info_struct>::iterator it; std::map<int64_t, global_id_info_struct>::iterator it;
for (it = map.begin(); it != map.end(); ++it) { for (it = map.begin(); it != map.end(); ++it) {
int64_t id = it->second.new_id; int64_t id = it->second.new_id;
std::set<int64_t>::const_iterator it2; 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; int64_t id2 = remote_map.find(*it2)->second;
id = std::min(id, id2); id = std::min(id, id2);
} }
@ -318,9 +321,9 @@ static bool updateLocalIds( const std::map<int64_t,int64_t>& remote_map,
} }
return changed; return changed;
} }
static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_info, static int LocalToGlobalIDs(int nx, int ny, int nz,
int nblobs, BlobIDArray& IDs, const Utilities::MPI& comm ) const RankInfoStruct &rank_info, int nblobs,
{ BlobIDArray &IDs, const Utilities::MPI &comm) {
PROFILE_START("LocalToGlobalIDs", 1); PROFILE_START("LocalToGlobalIDs", 1);
const int rank = rank_info.rank[1][1][1]; const int rank = rank_info.rank[1][1][1];
int nprocs = comm.getSize(); int nprocs = comm.getSize();
@ -346,7 +349,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
} }
const BlobIDArray LocalIDs = IDs; const BlobIDArray LocalIDs = IDs;
// Copy the ids and get the neighbors through the halos // 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); fillData.fill(IDs);
// Create a list of all neighbor ranks (excluding self) // Create a list of all neighbor ranks (excluding self)
std::vector<int> neighbors; std::vector<int> neighbors;
@ -357,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][0]);
neighbors.push_back(rank_info.rank[1][1][2]); neighbors.push_back(rank_info.rank[1][1][2]);
std::sort(neighbors.begin(), neighbors.end()); 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 // Create a map of all local ids to the neighbor ids
std::map<int64_t, global_id_info_struct> map; std::map<int64_t, global_id_info_struct> map;
std::set<int64_t> local; std::set<int64_t> local;
@ -394,7 +399,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
for (it = map.begin(); it != map.end(); ++it) { for (it = map.begin(); it != map.end(); ++it) {
int64_t id = it->first; int64_t id = it->first;
std::set<int64_t>::const_iterator it2; 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; int64_t id2 = *it2;
id = std::min(id, id2); id = std::min(id, id2);
remote_map.insert(std::pair<int64_t, int64_t>(id2, id2)); remote_map.insert(std::pair<int64_t, int64_t>(id2, id2));
@ -407,7 +413,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
while (1) { while (1) {
iteration++; iteration++;
// Send the local ids and their new value to all neighbors // 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 // Compute a new local id for each local id
bool changed = updateLocalIds(remote_map, map); bool changed = updateLocalIds(remote_map, map);
// Check if we are finished // Check if we are finished
@ -421,7 +428,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
std::vector<int> final_map(nblobs, -1); std::vector<int> final_map(nblobs, -1);
for (it = map.begin(); it != map.end(); ++it) for (it = map.begin(); it != map.end(); ++it)
final_map[it->first - offset] = it->second.new_id; 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; final_map[*it2 - offset] = *it2;
for (size_t i = 0; i < final_map.size(); i++) for (size_t i = 0; i < final_map.size(); i++)
ASSERT(final_map[i] >= 0); ASSERT(final_map[i] >= 0);
@ -435,7 +443,8 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
} }
} }
// Fill the ghosts // 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); fillData2.fill(IDs);
// Reorder based on size (and compress the id space // Reorder based on size (and compress the id space
int N_blobs_global = ReorderBlobIDs2(IDs, N_blobs_tot, ngx, ngy, ngz, comm); int N_blobs_global = ReorderBlobIDs2(IDs, N_blobs_tot, ngx, ngy, ngz, comm);
@ -446,38 +455,43 @@ static int LocalToGlobalIDs( int nx, int ny, int nz, const RankInfoStruct& rank_
PROFILE_STOP("LocalToGlobalIDs", 1); PROFILE_STOP("LocalToGlobalIDs", 1);
return N_blobs_global; return N_blobs_global;
} }
int ComputeGlobalBlobIDs( int nx, int ny, int nz, const RankInfoStruct& rank_info, int ComputeGlobalBlobIDs(int nx, int ny, int nz,
const DoubleArray& Phase, const DoubleArray& SignDist, double vF, double vS, const RankInfoStruct &rank_info,
BlobIDArray& GlobalBlobID, const Utilities::MPI& comm ) const DoubleArray &Phase, const DoubleArray &SignDist,
{ double vF, double vS, BlobIDArray &GlobalBlobID,
const Utilities::MPI &comm) {
PROFILE_START("ComputeGlobalBlobIDs"); PROFILE_START("ComputeGlobalBlobIDs");
// First compute the local ids // 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 // 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"); PROFILE_STOP("ComputeGlobalBlobIDs");
return nglobal; return nglobal;
} }
int ComputeGlobalPhaseComponent( int nx, int ny, int nz, const RankInfoStruct& rank_info, int ComputeGlobalPhaseComponent(int nx, int ny, int nz,
const IntArray &PhaseID, int &VALUE, BlobIDArray &GlobalBlobID, const Utilities::MPI& comm ) const RankInfoStruct &rank_info,
{ const IntArray &PhaseID, int &VALUE,
BlobIDArray &GlobalBlobID,
const Utilities::MPI &comm) {
PROFILE_START("ComputeGlobalPhaseComponent"); PROFILE_START("ComputeGlobalPhaseComponent");
// First compute the local ids // First compute the local ids
int nblobs = ComputeLocalPhaseComponent(PhaseID,VALUE,GlobalBlobID,false); int nblobs =
ComputeLocalPhaseComponent(PhaseID, VALUE, GlobalBlobID, false);
// Compute the global ids // 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"); PROFILE_STOP("ComputeGlobalPhaseComponent");
return nglobal; return nglobal;
} }
/****************************************************************** /******************************************************************
* Compute the mapping of blob ids between timesteps * * Compute the mapping of blob ids between timesteps *
******************************************************************/ ******************************************************************/
typedef std::map<BlobIDType, std::map<BlobIDType, int64_t>> map_type; typedef std::map<BlobIDType, std::map<BlobIDType, int64_t>> map_type;
template <class 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(); int nprocs = comm.getSize();
std::vector<TYPE> send_data(set.begin(), set.end()); std::vector<TYPE> send_data(set.begin(), set.end());
int send_count = send_data.size(); int send_count = send_data.size();
@ -491,8 +505,7 @@ void gatherSet( std::set<TYPE>& set, const Utilities::MPI& comm )
for (size_t i = 0; i < recv_data.size(); i++) for (size_t i = 0; i < recv_data.size(); i++)
set.insert(recv_data[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(); int nprocs = comm.getSize();
std::vector<int64_t> send_data; std::vector<int64_t> send_data;
for (auto it = src_map.begin(); it != src_map.end(); ++it) { for (auto it = src_map.begin(); it != src_map.end(); ++it) {
@ -511,9 +524,10 @@ void gatherSrcIDMap( map_type& src_map, const Utilities::MPI& comm )
comm.allGather(send_count, getPtr(recv_count)); comm.allGather(send_count, getPtr(recv_count));
for (int i = 1; i < nprocs; i++) for (int i = 1; i < nprocs; i++)
recv_disp[i] = recv_disp[i - 1] + recv_count[i - 1]; 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]); std::vector<int64_t> recv_data(recv_disp[nprocs - 1] +
comm.allGather(getPtr(send_data),send_count, recv_count[nprocs - 1]);
getPtr(recv_data),getPtr(recv_count),getPtr(recv_disp),true); comm.allGather(getPtr(send_data), send_count, getPtr(recv_data),
getPtr(recv_count), getPtr(recv_disp), true);
size_t i = 0; size_t i = 0;
src_map.clear(); src_map.clear();
while (i < recv_data.size()) { while (i < recv_data.size()) {
@ -524,25 +538,25 @@ void gatherSrcIDMap( map_type& src_map, const Utilities::MPI& comm )
for (size_t j = 0; j < count; j++, i += 2) { for (size_t j = 0; j < count; j++, i += 2) {
auto it = src_ids.find(recv_data[i]); auto it = src_ids.find(recv_data[i]);
if (it == src_ids.end()) 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 else
it->second += recv_data[i + 1]; it->second += recv_data[i + 1];
} }
} }
} }
void addSrcDstIDs(BlobIDType src_id, map_type &src_map, map_type &dst_map, 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); src.insert(src_id);
const std::map<BlobIDType, int64_t> &dst_ids = dst_map[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()) if (dst.find(it->first) == dst.end())
addSrcDstIDs(it->first, dst_map, src_map, dst, src); addSrcDstIDs(it->first, dst_map, src_map, dst, src);
} }
} }
ID_map_struct computeIDMap( int nx, int ny, int nz, ID_map_struct computeIDMap(int nx, int ny, int nz, const BlobIDArray &ID1,
const BlobIDArray& ID1, const BlobIDArray& ID2, const Utilities::MPI& comm ) const BlobIDArray &ID2, const Utilities::MPI &comm) {
{
ASSERT(ID1.size() == ID2.size()); ASSERT(ID1.size() == ID2.size());
PROFILE_START("computeIDMap"); PROFILE_START("computeIDMap");
const int ngx = (ID1.size(0) - nx) / 2; const int ngx = (ID1.size(0) - nx) / 2;
@ -563,7 +577,8 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
dst_set.insert(id2); dst_set.insert(id2);
if (id1 >= 0 && id2 >= 0) { if (id1 >= 0 && id2 >= 0) {
std::map<BlobIDType, int64_t> &src_ids = src_map[id2]; 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()) { if (it == src_ids.end()) {
src_ids.insert(std::pair<BlobIDType, int64_t>(id1, 0)); src_ids.insert(std::pair<BlobIDType, int64_t>(id1, 0));
it = src_ids.find(id1); it = src_ids.find(id1);
@ -579,10 +594,13 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
gatherSrcIDMap(src_map, comm); gatherSrcIDMap(src_map, comm);
// Compute the dst id map // Compute the dst id map
map_type dst_map; // Map of the dst ids for each src id 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; BlobIDType id = it->first;
const std::map<BlobIDType, int64_t> &src_ids = it->second; 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]; std::map<BlobIDType, int64_t> &dst_ids = dst_map[it2->first];
dst_ids.insert(std::pair<BlobIDType, int64_t>(id, it2->second)); dst_ids.insert(std::pair<BlobIDType, int64_t>(id, it2->second));
} }
@ -591,19 +609,22 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
// Perform the mapping of ids // Perform the mapping of ids
ID_map_struct id_map; ID_map_struct id_map;
// Find new blobs // 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()) if (src_map.find(*it) == src_map.end())
id_map.created.push_back(*it); id_map.created.push_back(*it);
} }
// Fine blobs that disappeared // 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()) if (dst_map.find(*it) == dst_map.end())
id_map.destroyed.push_back(*it); id_map.destroyed.push_back(*it);
} }
// Find blobs with a 1-to-1 mapping // Find blobs with a 1-to-1 mapping
std::vector<BlobIDType> dst_list; std::vector<BlobIDType> dst_list;
dst_list.reserve(src_map.size()); 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); dst_list.push_back(it->first);
for (size_t i = 0; i < dst_list.size(); i++) { for (size_t i = 0; i < dst_list.size(); i++) {
int dst_id = dst_list[i]; int dst_id = dst_list[i];
@ -615,7 +636,8 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
ASSERT(dst_ids.begin()->first == dst_id); ASSERT(dst_ids.begin()->first == dst_id);
src_map.erase(dst_id); src_map.erase(dst_id);
dst_map.erase(src_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));
} }
} }
} }
@ -626,30 +648,41 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
addSrcDstIDs(dst_map.begin()->first, src_map, dst_map, src, dst); addSrcDstIDs(dst_map.begin()->first, src_map, dst_map, src, dst);
if (src.size() == 1) { if (src.size() == 1) {
// Bubble split // 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) { } else if (dst.size() == 1) {
// Bubble merge // 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 { } else {
// Bubble split/merge // Bubble split/merge
id_map.merge_split.push_back(BlobIDMergeSplitStruct( 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 // 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]; 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); std::pair<BlobIDType, BlobIDType> id(*it1, *it2);
int64_t overlap = 0; int64_t overlap = 0;
const std::map<BlobIDType,int64_t>::const_iterator it = dst_ids.find(*it2); const std::map<BlobIDType, int64_t>::const_iterator it =
if ( it != dst_ids.end() ) { overlap = it->second; } dst_ids.find(*it2);
id_map.overlap.insert(std::pair<OverlapID,int64_t>(id,overlap)); if (it != dst_ids.end()) {
overlap = it->second;
}
id_map.overlap.insert(
std::pair<OverlapID, int64_t>(id, overlap));
} }
} }
// Clear the mapped entries // 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); 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); src_map.erase(*it);
} }
ASSERT(src_map.empty()); ASSERT(src_map.empty());
@ -658,14 +691,14 @@ ID_map_struct computeIDMap( int nx, int ny, int nz,
return id_map; return id_map;
} }
/****************************************************************** /******************************************************************
* Renumber the ids * * Renumber the ids *
******************************************************************/ ******************************************************************/
typedef std::vector<BlobIDType> IDvec; typedef std::vector<BlobIDType> IDvec;
inline void renumber( const std::vector<BlobIDType>& id1, const std::vector<BlobIDType>& id2, inline void renumber(const std::vector<BlobIDType> &id1,
const std::map<OverlapID,int64_t>& overlap, std::vector<BlobIDType>& new_ids, BlobIDType& id_max ) const std::vector<BlobIDType> &id2,
{ const std::map<OverlapID, int64_t> &overlap,
std::vector<BlobIDType> &new_ids, BlobIDType &id_max) {
if (id2.empty()) { if (id2.empty()) {
// No dst ids to set // No dst ids to set
} else if (id1.empty()) { } else if (id1.empty()) {
@ -687,7 +720,10 @@ inline void renumber( const std::vector<BlobIDType>& id1, const std::vector<Blob
Array<int64_t> cost(id1.size(), id2.size()); Array<int64_t> cost(id1.size(), id2.size());
for (size_t j = 0; j < id2.size(); j++) { for (size_t j = 0; j < id2.size(); j++) {
for (size_t i = 0; i < id1.size(); i++) { 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 // While we have not mapped all dst ids
@ -724,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]; 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++) for (size_t i = 0; i < ids.size(); i++)
ids[i] = new_ids[ids[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); new_ids.resize(0);
// Get the new id numbers for each map type // Get the new id numbers for each map type
for (size_t i = 0; i < map.src_dst.size(); i++) 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++) 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++) 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++) 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++) 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++) 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 // Renumber the ids in the map
for (size_t i = 0; i < map.src_dst.size(); i++) for (size_t i = 0; i < map.src_dst.size(); i++)
renumberIDs(new_ids, map.src_dst[i].second); renumberIDs(new_ids, map.src_dst[i].second);
@ -760,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++) for (size_t i = 0; i < map.merge_split.size(); i++)
renumberIDs(new_ids, map.merge_split[i].second); renumberIDs(new_ids, map.merge_split[i].second);
std::map<OverlapID, int64_t> overlap2; 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; OverlapID id = it->first;
renumberIDs(new_ids, id.second); renumberIDs(new_ids, id.second);
overlap2.insert(std::pair<OverlapID, int64_t>(id, it->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(); size_t N = IDs.length();
BlobIDType *ids = IDs.data(); BlobIDType *ids = IDs.data();
for (size_t i = 0; i < N; i++) { for (size_t i = 0; i < N; i++) {
@ -777,17 +819,17 @@ void renumberIDs( const std::vector<BlobIDType>& new_ids, BlobIDArray& IDs )
} }
} }
/****************************************************************** /******************************************************************
* Write the id map for the given timestep * * 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(); int rank = Utilities::MPI(MPI_COMM_WORLD).getRank();
if (rank != 0) if (rank != 0)
return; return;
bool empty = map.created.empty() && map.destroyed.empty() && 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++) for (size_t i = 0; i < map.src_dst.size(); i++)
empty = empty && map.src_dst[i].first == map.src_dst[i].second; empty = empty && map.src_dst[i].first == map.src_dst[i].second;
if (timestep != 0 && empty) if (timestep != 0 && empty)
@ -809,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])); fprintf(fid, " %lli-", static_cast<long long int>(map.destroyed[i]));
for (size_t i = 0; i < map.src_dst.size(); i++) { for (size_t i = 0; i < map.src_dst.size(); i++) {
if (map.src_dst[i].first != map.src_dst[i].second) 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)); static_cast<long long int>(map.src_dst[i].second));
} }
for (size_t i = 0; i < map.split.size(); i++) { 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])); static_cast<long long int>(map.split[i].second[0]));
for (size_t j = 1; j < map.split[i].second.size(); j++) 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++) { 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++) 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)); fprintf(fid, "-%lli", static_cast<long long int>(map.merge[i].second));
} }
for (size_t i = 0; i < map.merge_split.size(); i++) { 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++) 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",
fprintf(fid,"-%lli",static_cast<long long int>(map.merge_split[i].second[0])); 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++) 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"); fprintf(fid, "\n");
fclose(fid); fclose(fid);
} }

View File

@ -24,12 +24,10 @@
#include <map> #include <map>
#include <vector> #include <vector>
// Define types to use for blob ids // Define types to use for blob ids
typedef int32_t BlobIDType; typedef int32_t BlobIDType;
typedef Array<BlobIDType> BlobIDArray; typedef Array<BlobIDType> BlobIDArray;
/*! /*!
* @brief Compute the blob * @brief Compute the blob
* @details Compute the blob (F>vf|S>vs) starting from (i,j,k) - oil blob * @details Compute the blob (F>vf|S>vs) starting from (i,j,k) - oil blob
@ -43,7 +41,8 @@ typedef Array<BlobIDType> BlobIDArray;
* @return Returns the number of blobs * @return Returns the number of blobs
*/ */
int ComputeLocalBlobIDs(const DoubleArray &Phase, const DoubleArray &SignDist, 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 * @brief Compute blob of an arbitrary phase
@ -54,8 +53,8 @@ int ComputeLocalBlobIDs( const DoubleArray& Phase, const DoubleArray& SignDist,
* @param[out] ComponentLabel * @param[out] ComponentLabel
* @param[in] periodic * @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 * @brief Compute the blob
@ -73,10 +72,11 @@ int ComputeLocalPhaseComponent( const IntArray &PhaseID, int &VALUE, IntArray &C
* @param[in] comm MPI communicator * @param[in] comm MPI communicator
* @return Returns the number of blobs * @return Returns the number of blobs
*/ */
int ComputeGlobalBlobIDs( int nx, int ny, int nz, const RankInfoStruct& rank_info, int ComputeGlobalBlobIDs(int nx, int ny, int nz,
const DoubleArray& Phase, const DoubleArray& SignDist, double vF, double vS, const RankInfoStruct &rank_info,
BlobIDArray& GlobalBlobID, const Utilities::MPI& comm ); const DoubleArray &Phase, const DoubleArray &SignDist,
double vF, double vS, BlobIDArray &GlobalBlobID,
const Utilities::MPI &comm);
/*! /*!
* @brief Compute component of the specified phase * @brief Compute component of the specified phase
@ -92,9 +92,11 @@ int ComputeGlobalBlobIDs( int nx, int ny, int nz, const RankInfoStruct& rank_inf
* @param[in] comm The communicator to use * @param[in] comm The communicator to use
* @return Return the number of components in the specified phase * @return Return the number of components in the specified phase
*/ */
int ComputeGlobalPhaseComponent( int nx, int ny, int nz, const RankInfoStruct& rank_info, int ComputeGlobalPhaseComponent(int nx, int ny, int nz,
const IntArray &PhaseID, int &VALUE, BlobIDArray &GlobalBlobID, const Utilities::MPI& comm ); const RankInfoStruct &rank_info,
const IntArray &PhaseID, int &VALUE,
BlobIDArray &GlobalBlobID,
const Utilities::MPI &comm);
/*! /*!
* @brief Reorder the blobs * @brief Reorder the blobs
@ -105,29 +107,33 @@ int ComputeGlobalPhaseComponent( int nx, int ny, int nz, const RankInfoStruct& r
*/ */
void ReorderBlobIDs(BlobIDArray &ID, const Utilities::MPI &comm); void ReorderBlobIDs(BlobIDArray &ID, const Utilities::MPI &comm);
typedef std::pair<BlobIDType, std::vector<BlobIDType>> BlobIDSplitStruct; typedef std::pair<BlobIDType, std::vector<BlobIDType>> BlobIDSplitStruct;
typedef std::pair<std::vector<BlobIDType>, BlobIDType> BlobIDMergeStruct; 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; typedef std::pair<BlobIDType, BlobIDType> OverlapID;
struct ID_map_struct { struct ID_map_struct {
std::vector<BlobIDType> created; // list of new blobs that were created std::vector<BlobIDType> created; // list of new blobs that were created
std::vector<BlobIDType> destroyed; // list of blobs that disappeared 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<BlobIDSplitStruct> split; // list of blobs that split
std::vector<BlobIDMergeStruct> merge; // list of blobs that merged std::vector<BlobIDMergeStruct> merge; // list of blobs that merged
std::vector<BlobIDMergeSplitStruct> merge_split; // list of blobs that both merged and split std::vector<BlobIDMergeSplitStruct>
std::map<OverlapID,int64_t> overlap; // for ids that are not a 1-1 mapping, this is a list of the overlaps <src,dst> 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 //! Empty constructor
ID_map_struct() {} ID_map_struct() {}
//! Create initial map from N blobs (ordered 1:N-1) //! Create initial map from N blobs (ordered 1:N-1)
ID_map_struct(int N) { ID_map_struct(int N) {
created.resize(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 * @brief Get the mapping of blob ids between iterations
* @details This functions computes the map of blob ids between iterations * @details This functions computes the map of blob ids between iterations
@ -140,8 +146,8 @@ struct ID_map_struct {
* @param[in] ID2 The blob ids at the second timestep * @param[in] ID2 The blob ids at the second timestep
* @param[in] comm The communicator to use * @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 * @brief Compute the new global ids based on the map
@ -151,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[in] id_max The globally largest id used previously
* @param[out] new_ids The newly renumbered blob ids (0:ids.max()) * @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 * @brief Update the blob ids based on mapping
@ -163,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); void renumberIDs(const std::vector<BlobIDType> &new_ids, BlobIDArray &IDs);
/*! /*!
* @brief Write the ID map * @brief Write the ID map
* @details This functions writes the id map fo an iteration. * @details This functions writes the id map fo an iteration.
@ -173,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] timestep The current timestep (timestep 0 creates the file)
* @param[in] filename The filename to write/append * @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 #endif

View File

@ -1,17 +1,13 @@
#include "analysis/dcel.h" #include "analysis/dcel.h"
DCEL::DCEL(){ DCEL::DCEL() {}
}
DCEL::~DCEL() { DCEL::~DCEL() {
TriangleCount = 0; TriangleCount = 0;
VertexCount = 0; VertexCount = 0;
} }
int DCEL::Face(int index){ int DCEL::Face(int index) { return FaceData[index]; }
return FaceData[index];
}
void DCEL::Write() { void DCEL::Write() {
int e1, e2, e3; int e1, e2, e3;
@ -32,7 +28,8 @@ void DCEL::Write(){
fclose(TRIANGLES); 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 P, Q;
Point PlaceHolder; Point PlaceHolder;
Point C0, C1, C2, C3, C4, C5, C6, C7; 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]; double CubeValues[8];
// Points corresponding to cube corners // Points corresponding to cube corners
C0.x = 0.0; C0.y = 0.0; C0.z = 0.0; C0.x = 0.0;
C1.x = 1.0; C1.y = 0.0; C1.z = 0.0; C0.y = 0.0;
C2.x = 1.0; C2.y = 1.0; C2.z = 0.0; C0.z = 0.0;
C3.x = 0.0; C3.y = 1.0; C3.z = 0.0; C1.x = 1.0;
C4.x = 0.0; C4.y = 0.0; C4.z = 1.0; C1.y = 0.0;
C5.x = 1.0; C5.y = 0.0; C5.z = 1.0; C1.z = 0.0;
C6.x = 1.0; C6.y = 1.0; C6.z = 1.0; C2.x = 1.0;
C7.x = 0.0; C7.y = 1.0; C7.z = 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[0] = A(i, j, k) - value;
CubeValues[1] = A(i + 1, 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 //Determine the index into the edge table which
//tells us which vertices are inside of the surface //tells us which vertices are inside of the surface
int CubeIndex = 0; int CubeIndex = 0;
if (CubeValues[0] < 0.0f) CubeIndex |= 1; if (CubeValues[0] < 0.0f)
if (CubeValues[1] < 0.0f) CubeIndex |= 2; CubeIndex |= 1;
if (CubeValues[2] < 0.0f) CubeIndex |= 4; if (CubeValues[1] < 0.0f)
if (CubeValues[3] < 0.0f) CubeIndex |= 8; CubeIndex |= 2;
if (CubeValues[4] < 0.0f) CubeIndex |= 16; if (CubeValues[2] < 0.0f)
if (CubeValues[5] < 0.0f) CubeIndex |= 32; CubeIndex |= 4;
if (CubeValues[6] < 0.0f) CubeIndex |= 64; if (CubeValues[3] < 0.0f)
if (CubeValues[7] < 0.0f) CubeIndex |= 128; 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 //Find the vertices where the surface intersects the cube
if (edgeTable[CubeIndex] & 1) { 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++) for (int idx = 0; idx < 12; idx++)
LocalRemap[idx] = -1; LocalRemap[idx] = -1;
for (int idx=0;triTable[CubeIndex][idx]!=-1;idx++) for (int idx = 0; triTable[CubeIndex][idx] != -1; idx++) {
{ if (LocalRemap[triTable[CubeIndex][idx]] == -1) {
if(LocalRemap[triTable[CubeIndex][idx]] == -1)
{
NewVertexList[VertexCount] = VertexList[triTable[CubeIndex][idx]]; NewVertexList[VertexCount] = VertexList[triTable[CubeIndex][idx]];
LocalRemap[triTable[CubeIndex][idx]] = VertexCount; LocalRemap[triTable[CubeIndex][idx]] = VertexCount;
VertexCount++; VertexCount++;
@ -219,24 +238,33 @@ void DCEL::LocalIsosurface(const DoubleArray& A, double value, const int i, cons
int V2 = halfedge.data(1, idx); int V2 = halfedge.data(1, idx);
// Find all the twins within the cube // Find all the twins within the cube
for (int jdx = 0; jdx < EdgeCount; jdx++) { 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 // this is the pair
halfedge.data(3, idx) = jdx; halfedge.data(3, idx) = jdx;
halfedge.data(3, jdx) = idx; halfedge.data(3, jdx) = idx;
} }
if (halfedge.data(1,jdx) == V2 && halfedge.data(0,jdx) == V1 && !(idx==jdx)){ if (halfedge.data(1, jdx) == V2 &&
std::printf("WARNING: half edges with identical orientation! \n"); 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 // Use "ghost" twins if edge is on a cube face
P = cellvertices[V1]; P = cellvertices[V1];
Q = cellvertices[V2]; 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 == 0.0 && Q.x == 0.0)
if (P.x == 1.0 && Q.x == 1.0) halfedge.data(3,idx) = -4; // ghost twin for x=1 face halfedge.data(3, idx) = -1; // ghost twin for x=0 face
if (P.y == 0.0 && Q.y == 0.0) halfedge.data(3,idx) = -2; // ghost twin for y=0 face if (P.x == 1.0 && Q.x == 1.0)
if (P.y == 1.0 && Q.y == 1.0) halfedge.data(3,idx) = -5; // ghost twin for y=1 face halfedge.data(3, idx) = -4; // ghost twin for x=1 face
if (P.z == 0.0 && Q.z == 0.0) halfedge.data(3,idx) = -3; // ghost twin for z=0 face if (P.y == 0.0 && Q.y == 0.0)
if (P.z == 1.0 && Q.z == 1.0) halfedge.data(3,idx) = -6; // ghost twin for z=1 face 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 P, Q, R;
Point U, V, W; Point U, V, W;
double nx, ny, nz, len; double nx, ny, nz, len;
// at cube faces define outward normal to cube // at cube faces define outward normal to cube
if (edge == -1) { if (edge == -1) {
W.x = -1.0; W.y = 0.0; W.z = 0.0; // x cube face W.x = -1.0;
} W.y = 0.0;
else if (edge == -2){ W.z = 0.0; // x cube face
W.x = 0.0; W.y = -1.0; W.z = 0.0; // y cube face } else if (edge == -2) {
} W.x = 0.0;
else if (edge == -3){ W.y = -1.0;
W.x = 0.0; W.y = 0.0; W.z = -1.0; // z cube face W.z = 0.0; // y cube face
} } else if (edge == -3) {
else if (edge == -4){ W.x = 0.0;
W.x = 1.0; W.y = 0.0; W.z = 0.0; // x cube face W.y = 0.0;
} W.z = -1.0; // z cube face
else if (edge == -5){ } else if (edge == -4) {
W.x = 0.0; W.y = 1.0; W.z = 0.0; // y cube face W.x = 1.0;
} W.y = 0.0;
else if (edge == -6){ W.z = 0.0; // x cube face
W.x = 0.0; W.y = 0.0; W.z = 1.0; // z cube face } else if (edge == -5) {
} W.x = 0.0;
else{ 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 // vertices for triange
int e2 = halfedge.next(edge); int e2 = halfedge.next(edge);
int e3 = halfedge.next(e2); int e3 = halfedge.next(e2);
@ -289,13 +322,14 @@ Point DCEL::TriNormal(int edge)
ny = U.z * V.x - U.x * V.z; ny = U.z * V.x - U.x * V.z;
nz = U.x * V.y - U.y * V.x; nz = U.x * V.y - U.y * V.x;
len = sqrt(nx * nx + ny * ny + nz * nz); 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; return W;
} }
double DCEL::EdgeAngle(int edge) double DCEL::EdgeAngle(int edge) {
{
double angle; double angle;
double dotprod; double dotprod;
Point P, Q, R; // triangle vertices 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; double nz = W.x * V.y - W.y * V.x;
length = sqrt(nx * nx + ny * ny + nz * nz); length = sqrt(nx * nx + ny * ny + nz * nz);
// new value for V is this normal vector // 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; dotprod = U.x * V.x + U.y * V.y + U.z * V.z;
if (dotprod < 0.f) { if (dotprod < 0.f) {
//printf("negative dot product on face\n"); //printf("negative dot product on face\n");
dotprod = -dotprod; 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)
if (dotprod < -1.f) dotprod=-1.f; dotprod = 1.f;
if (dotprod < -1.f)
dotprod = -1.f;
angle = acos(dotprod); angle = acos(dotprod);
/* project onto plane of cube face also works /* project onto plane of cube face also works
W = U - dotprod*V; W = U - dotprod*V;
@ -339,11 +379,12 @@ double DCEL::EdgeAngle(int edge)
if (dotprod < -1.f) dotprod=-1.f; if (dotprod < -1.f) dotprod=-1.f;
angle = acos(dotprod); angle = acos(dotprod);
*/ */
} } else {
else{
dotprod = U.x * V.x + U.y * V.y + U.z * V.z; dotprod = U.x * V.x + U.y * V.y + U.z * V.z;
if (dotprod > 1.f) dotprod=1.f; if (dotprod > 1.f)
if (dotprod < -1.f) dotprod=-1.f; dotprod = 1.f;
if (dotprod < -1.f)
dotprod = -1.f;
angle = 0.5 * acos(dotprod); angle = 0.5 * acos(dotprod);
} }
// determine if angle is concave or convex based on edge normal // determine if angle is concave or convex based on edge normal
@ -362,13 +403,13 @@ double DCEL::EdgeAngle(int edge)
// concave // concave
angle = -angle; 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); //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; return angle;
} }
void iso_surface(const Array<double>&Field, const double isovalue) void iso_surface(const Array<double> &Field, const double isovalue) {
{
DCEL object; DCEL object;
int e1, e2, e3; int e1, e2, e3;
FILE *TRIANGLES; 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; // 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; //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; //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, " outer loop\n");
fprintf(TRIANGLES," vertex %f %f %f\n",P1.x,P1.y,P1.z); fprintf(TRIANGLES, " vertex %f %f %f\n", P1.x, P1.y,
fprintf(TRIANGLES," vertex %f %f %f\n",P2.x,P2.y,P2.z); P1.z);
fprintf(TRIANGLES," vertex %f %f %f\n",P3.x,P3.y,P3.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, " endloop\n");
fprintf(TRIANGLES, "endfacet\n"); fprintf(TRIANGLES, "endfacet\n");
} }
} }
} }

View File

@ -34,7 +34,6 @@ private:
std::vector<Point> d_data; std::vector<Point> d_data;
}; };
/** /**
* \class Halfedge * \class Halfedge
* @brief store half edge for DCEL data structure * @brief store half edge for DCEL data structure
@ -75,7 +74,8 @@ public:
int face(); int face();
Vertex vertex; Vertex vertex;
Halfedge halfedge; 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(); void Write();
int Face(int index); int Face(int index);

View File

@ -16,18 +16,17 @@
*/ */
#include "analysis/distance.h" #include "analysis/distance.h"
/****************************************************************** /******************************************************************
* A fast distance calculation * * A fast distance calculation *
******************************************************************/ ******************************************************************/
template <class TYPE> template <class TYPE>
void CalcDist(Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm, 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()); ASSERT(Distance.size() == ID.size());
std::array<int, 3> n = {Dm.Nx - 2, Dm.Ny - 2, Dm.Nz - 2}; 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<int> id(ID.size());
Array<Vec> vecDist(Distance.size()); Array<Vec> vecDist(Distance.size());
for (size_t i = 0; i < ID.length(); i++) for (size_t i = 0; i < ID.length(); i++)
@ -38,13 +37,12 @@ void CalcDist( Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm,
Distance(i) = id(i) * vecDist(i).norm(); Distance(i) = id(i) * vecDist(i).norm();
} }
/****************************************************************** /******************************************************************
* Vector-based distance calculation * * Vector-based distance calculation *
* Initialize cells adjacent to boundaries * * 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)); d.fill(Vec(1e50, 1e50, 1e50));
const double dx0 = 0.5 * dx; const double dx0 = 0.5 * dx;
const double dy0 = 0.5 * dy; const double dy0 = 0.5 * dy;
@ -63,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 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 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)}; 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[0])
if ( x[1] ) d(i,j,k) = Vec( -dx0, 0, 0 ); d(i, j, k) = Vec(dx0, 0, 0);
if ( y[0] ) d(i,j,k) = Vec( 0, dy0, 0 ); if (x[1])
if ( y[1] ) d(i,j,k) = Vec( 0, -dy0, 0 ); d(i, j, k) = Vec(-dx0, 0, 0);
if ( z[0] ) d(i,j,k) = Vec( 0, 0, dz0 ); if (y[0])
if ( z[1] ) d(i,j,k) = Vec( 0, 0, -dz0 ); 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[0] ) d(i,j,k) = Vec( dxy0, dxy0, 0 );
if ( x[0] && y[1] ) 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 ); if ( x[1] && y[0] ) d(i,j,k) = Vec( -dxy0, dxy0, 0 );
@ -84,16 +88,14 @@ static void calcVecInitialize( Array<Vec> &d, const Array<int> &ID, double dx, d
} }
} }
} }
} }
/****************************************************************** /******************************************************************
* Vector-based distance calculation * * Vector-based distance calculation *
* Update interior cells * * 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; double err = 0;
int Nx = d.size(0); int Nx = d.size(0);
int Ny = d.size(1); int Ny = d.size(1);
@ -141,18 +143,18 @@ static double calcVecUpdateInterior( Array<Vec> &d, double dx, double dy, double
return err; return err;
} }
/****************************************************************** /******************************************************************
* Vector-based distance calculation * * Vector-based distance calculation *
******************************************************************/ ******************************************************************/
void CalcVecDist(Array<Vec> &d, const Array<int> &ID0, const Domain &Dm, 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, Dm.Ny, Dm.Nz};
std::array<int, 3> n = {Dm.Nx - 2, Dm.Ny - 2, Dm.Nz - 2}; std::array<int, 3> n = {Dm.Nx - 2, Dm.Ny - 2, Dm.Nz - 2};
// Create ID with ghosts // Create ID with ghosts
Array<int> ID(N[0], N[1], N[2]); 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); fillDataID.copy(ID0, ID);
// Fill ghosts with nearest neighbor // Fill ghosts with nearest neighbor
for (int k = 1; k < N[2] - 1; k++) { for (int k = 1; k < N[2] - 1; k++) {
@ -176,7 +178,8 @@ void CalcVecDist( Array<Vec> &d, const Array<int> &ID0, const Domain &Dm,
// Communicate ghosts // Communicate ghosts
fillDataID.fill(ID); fillDataID.fill(ID);
// Create communicator for distance // 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 // Calculate the local distances
calcVecInitialize(d, ID, dx[0], dx[1], dx[2]); calcVecInitialize(d, ID, dx[0], dx[1], dx[2]);
double err = 1e100; double err = 1e100;
@ -198,9 +201,10 @@ void CalcVecDist( Array<Vec> &d, const Array<int> &ID0, const Domain &Dm,
} }
} }
// Explicit instantiations // 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<float>(Array<float> &, const Array<char> &,
template void CalcDist<double>( Array<double>&, const Array<char>&, const Domain&, const std::array<bool,3>&, const std::array<double,3>& ); 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> &);

View File

@ -20,7 +20,6 @@
#include "common/Domain.h" #include "common/Domain.h"
#include "common/Array.hpp" #include "common/Array.hpp"
struct Vec { struct Vec {
double x; double x;
double y; double y;
@ -30,8 +29,10 @@ struct Vec {
inline double norm() const { return sqrt(x * x + y * y + z * z); } inline double norm() const { return sqrt(x * x + y * y + z * z); }
inline double norm2() const { return 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 * @brief Calculate the distance using a simple method
@ -44,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> template <class TYPE>
void CalcDist(Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm, 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 * @brief Calculate the distance using a simple method
@ -56,6 +58,7 @@ void CalcDist( Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm,
* @param[in] dx Cell size * @param[in] dx Cell size
*/ */
void CalcVecDist(Array<Vec> &Distance, const Array<int> &ID, const Domain &Dm, 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 #endif

View File

@ -18,8 +18,7 @@
#include "math.h" #include "math.h"
#include "ProfilerApp.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"); PROFILE_START("Mean3D");
// Perform a 3D Mean filter on Input array // Perform a 3D Mean filter on Input array
int i, j, k; int i, j, k;
@ -33,12 +32,21 @@ void Mean3D( const Array<double> &Input, Array<double> &Output )
for (i = 1; i < Nx - 1; i++) { for (i = 1; i < Nx - 1; i++) {
double MeanValue = Input(i, j, k); double MeanValue = Input(i, j, k);
// next neighbors // 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, k) + Input(i, j + 1, k) +
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); Input(i, j, k + 1) + Input(i - 1, j, 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); Input(i, j - 1, k) + Input(i, 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) + Input(i - 1, j + 1, k) +
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); Input(i + 1, j - 1, k) + Input(i - 1, j - 1, k);
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 + 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; Output(i, j, k) = MeanValue / 27.0;
} }
} }
@ -46,8 +54,7 @@ void Mean3D( const Array<double> &Input, Array<double> &Output )
PROFILE_STOP("Mean3D"); PROFILE_STOP("Mean3D");
} }
void Med3D( const Array<float> &Input, Array<float> &Output ) void Med3D(const Array<float> &Input, Array<float> &Output) {
{
PROFILE_START("Med3D"); PROFILE_START("Med3D");
// Perform a 3D Median filter on Input array with specified width // Perform a 3D Median filter on Input array with specified width
int i, j, k, ii, jj, kk; int i, j, k, ii, jj, kk;
@ -99,10 +106,9 @@ void Med3D( const Array<float> &Input, Array<float> &Output )
PROFILE_STOP("Med3D"); PROFILE_STOP("Med3D");
} }
int NLM3D(const Array<float> &Input, Array<float> &Mean, 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"); PROFILE_START("NLM3D");
// Implemenation of 3D non-local means filter // Implemenation of 3D non-local means filter
// d determines the width of the search volume // d determines the width of the search volume
@ -133,7 +139,8 @@ int NLM3D( const Array<float> &Input, Array<float> &Mean,
kmax = std::min(Nz - 1, k + d); kmax = std::min(Nz - 1, k + d);
// Populate the list with values in the window // Populate the list with values in the window
sum = 0; weight=0; sum = 0;
weight = 0;
for (kk = kmin; kk < kmax; kk++) { for (kk = kmin; kk < kmax; kk++) {
for (jj = jmin; jj < jmax; jj++) { for (jj = jmin; jj < jmax; jj++) {
for (ii = imin; ii < imax; ii++) { for (ii = imin; ii < imax; ii++) {
@ -153,10 +160,10 @@ int NLM3D( const Array<float> &Input, Array<float> &Mean,
for (j = 1; j < Ny - 1; j++) { for (j = 1; j < Ny - 1; j++) {
for (i = 1; i < Nx - 1; i++) { for (i = 1; i < Nx - 1; i++) {
if (fabs(Distance(i, j, k)) < THRESHOLD_DIST) { if (fabs(Distance(i, j, k)) < THRESHOLD_DIST) {
// compute the expensive non-local means // compute the expensive non-local means
sum = 0; weight=0; sum = 0;
weight = 0;
imin = std::max(0, i - d); imin = std::max(0, i - d);
jmin = std::max(0, j - d); jmin = std::max(0, j - d);
@ -178,8 +185,7 @@ int NLM3D( const Array<float> &Input, Array<float> &Mean,
returnCount++; returnCount++;
//Output(i,j,k) = Mean(i,j,k); //Output(i,j,k) = Mean(i,j,k);
Output(i, j, k) = sum / weight; Output(i, j, k) = sum / weight;
} } else {
else{
// Just return the mean // Just return the mean
Output(i, j, k) = Mean(i, j, k); Output(i, j, k) = Mean(i, j, k);
} }

View File

@ -17,7 +17,6 @@
#ifndef Filters_H_INC #ifndef Filters_H_INC
#define Filters_H_INC #define Filters_H_INC
#include "common/Array.h" #include "common/Array.h"
/*! /*!
@ -47,7 +46,7 @@ void Med3D( const Array<float> &Input, Array<float> &Output );
* @param[in] h * @param[in] h
*/ */
int NLM3D(const Array<float> &Input, Array<float> &Mean, 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 #endif

View File

@ -28,18 +28,19 @@ struct Histogram{
maximum = v2; maximum = v2;
delta = (maximum - minimum) / HISTOGRAM_RESOLUTION; delta = (maximum - minimum) / HISTOGRAM_RESOLUTION;
} }
~Histogram{ ~Histogram { delete *data; }
delete *data;
}
double *data; double *data;
double minimum, maximum, delta; double minimum, maximum, delta;
// Adds value into the histogram // Adds value into the histogram
void IncludeValue(double value, double weight) { void IncludeValue(double value, double weight) {
idx = floor((value - min) / delta); idx = floor((value - min) / delta);
if (idx > HISTOGRAM_RESOLUTION) ; if (idx > HISTOGRAM_RESOLUTION)
else if (idx < 0) ; ;
else data[idx] += weight; else if (idx < 0)
;
else
data[idx] += weight;
} }
// Returns the maximum value in the histogram // Returns the maximum value in the histogram
@ -54,7 +55,8 @@ struct Histogram{
// Resets the histogram to zero // Resets the histogram to zero
void Reset() { 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: private:

View File

@ -22,14 +22,11 @@
#include "common/Array.h" #include "common/Array.h"
#include <vector> #include <vector>
namespace imfilter { namespace imfilter {
//! enum to store the BC type //! enum to store the BC type
enum class BC { fixed = 0, symmetric = 1, replicate = 2, circular = 3 }; enum class BC { fixed = 0, symmetric = 1, replicate = 2, circular = 3 };
/*! /*!
* @brief N-D filtering of multidimensional images * @brief N-D filtering of multidimensional images
* @details imfilter filters the multidimensional array A with the * @details imfilter filters the multidimensional array A with the
@ -48,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) * @param[in] X The value to use for boundary conditions (only used if boundary==fixed)
*/ */
template <class TYPE> 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 * @brief N-D filtering of multidimensional images
@ -73,8 +71,8 @@ Array<TYPE> imfilter( const Array<TYPE>& A, const Array<TYPE>& H, const std::vec
template <class TYPE> template <class TYPE>
Array<TYPE> imfilter(const Array<TYPE> &A, const std::vector<int> &Nh, Array<TYPE> imfilter(const Array<TYPE> &A, const std::vector<int> &Nh,
std::function<TYPE(const Array<TYPE> &)> H, 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 * @brief N-D filtering of multidimensional images
@ -95,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) * @param[in] X The value to use for boundary conditions (only used if boundary==fixed)
*/ */
template <class TYPE> 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); const std::vector<imfilter::BC> &boundary, const TYPE X = 0);
/*! /*!
* @brief N-D filtering of multidimensional images * @brief N-D filtering of multidimensional images
* @details imfilter filters the multidimensional array A with the * @details imfilter filters the multidimensional array A with the
@ -118,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) * @param[in] X The value to use for boundary conditions (only used if boundary==fixed)
*/ */
template <class TYPE> 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, std::vector<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 * @brief N-D filtering of multidimensional images
* @details imfilter filters the multidimensional array A with the * @details imfilter filters the multidimensional array A with the
@ -143,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) * @param[in] X The value to use for boundary conditions (only used if boundary==fixed)
*/ */
template <class TYPE> 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, std::vector<std::function<TYPE(int, const TYPE *)>> H,
const std::vector<imfilter::BC> &boundary, const TYPE X = 0); const std::vector<imfilter::BC> &boundary, const TYPE X = 0);
/** /**
* @brief Create a filter to use with imfilter * @brief Create a filter to use with imfilter
* @details This function creates one of several predefined filters * @details This function creates one of several predefined filters
@ -164,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 * \param[in] args An optional argument that some of the filters use
*/ */
template <class TYPE> 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" #include "analysis/imfilter.hpp"
#endif #endif

View File

@ -35,15 +35,13 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#define IMFILTER_INSIST INSIST #define IMFILTER_INSIST INSIST
#define IMFILTER_ASSERT ASSERT #define IMFILTER_ASSERT ASSERT
#define IMFILTER_ERROR ERROR #define IMFILTER_ERROR ERROR
// Function to convert an index // 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 (index < 0 || index >= N) {
if (bc == imfilter::BC::symmetric) { if (bc == imfilter::BC::symmetric) {
index = (2 * N - index) % N; index = (2 * N - index) % N;
@ -58,12 +56,11 @@ static inline int imfilter_index( int index, const int N, const imfilter::BC bc
return index; return index;
} }
// Function to copy a 1D array and pad with the appropriate BC // Function to copy a 1D array and pad with the appropriate BC
template <class TYPE> template <class TYPE>
static inline void copy_array(const int N, const int Ns, const int Nh, 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 // Fill the center with a memcpy
for (int i = 0; i < N; i++) for (int i = 0; i < N; i++)
B[i + Nh] = A[i * Ns]; B[i + Nh] = A[i * Ns];
@ -76,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 * * Perform a 1D filter in a single direction *
********************************************************/ ********************************************************/
template <class TYPE> template <class TYPE>
static void filter_direction(int Ns, int N, int Ne, int Nh, const TYPE *H, 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) if (Nh < 0)
IMFILTER_ERROR("Invalid filter size"); IMFILTER_ERROR("Invalid filter size");
if (Nh == 0) { if (Nh == 0) {
@ -107,8 +102,8 @@ static void filter_direction( int Ns, int N, int Ne, int Nh, const TYPE *H,
} }
template <class TYPE> template <class TYPE>
static void filter_direction(int Ns, int N, int Ne, int Nh, 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) if (Nh < 0)
IMFILTER_ERROR("Invalid filter size"); IMFILTER_ERROR("Invalid filter size");
TYPE *tmp = new TYPE[N + 2 * Nh]; TYPE *tmp = new TYPE[N + 2 * Nh];
@ -127,8 +122,8 @@ static void filter_direction( int Ns, int N, int Ne, int Nh,
} }
template <class TYPE> template <class TYPE>
static void filter_direction(int Ns, int N, int Ne, int Nh, 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) if (Nh < 0)
IMFILTER_ERROR("Invalid filter size"); IMFILTER_ERROR("Invalid filter size");
TYPE *tmp = new TYPE[N + 2 * Nh]; TYPE *tmp = new TYPE[N + 2 * Nh];
@ -143,14 +138,12 @@ static void filter_direction( int Ns, int N, int Ne, int Nh,
delete[] tmp; delete[] tmp;
} }
/******************************************************** /********************************************************
* Create a filter * * Create a filter *
********************************************************/ ********************************************************/
template <class TYPE> 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()); std::vector<size_t> N2(N0.size());
for (size_t i = 0; i < N2.size(); i++) for (size_t i = 0; i < N2.size(); i++)
N2[i] = 2 * N0[i] + 1; N2[i] = 2 * N0[i] + 1;
@ -188,12 +181,10 @@ Array<TYPE> imfilter::create_filter( const std::vector<int>& N0, const std::stri
return h; return h;
} }
// Perform 2-D filtering // Perform 2-D filtering
template <class TYPE> template <class TYPE>
void imfilter_2D(int Nx, int Ny, const TYPE *A, int Nhx, int Nhy, const TYPE *H, 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); IMFILTER_ASSERT(A != B);
PROFILE_START("imfilter_2D"); PROFILE_START("imfilter_2D");
memset(B, 0, Nx * Ny * sizeof(TYPE)); memset(B, 0, Nx * Ny * sizeof(TYPE));
@ -225,13 +216,11 @@ void imfilter_2D( int Nx, int Ny, const TYPE *A, int Nhx, int Nhy, const TYPE *H
PROFILE_STOP("imfilter_2D"); PROFILE_STOP("imfilter_2D");
} }
// Perform 3-D filtering // Perform 3-D filtering
template <class TYPE> template <class TYPE>
void imfilter_3D( int Nx, int Ny, int Nz, const TYPE *A, int Nhx, int Nhy, int Nhz, void imfilter_3D(int Nx, int Ny, int Nz, const TYPE *A, int Nhx, int Nhy,
const TYPE *H, imfilter::BC BCx, imfilter::BC BCy, imfilter::BC BCz, int Nhz, const TYPE *H, imfilter::BC BCx, imfilter::BC BCy,
const TYPE X, TYPE *B ) imfilter::BC BCz, const TYPE X, TYPE *B) {
{
IMFILTER_ASSERT(A != B); IMFILTER_ASSERT(A != B);
PROFILE_START("imfilter_3D"); PROFILE_START("imfilter_3D");
memset(B, 0, Nx * Ny * Nz * sizeof(TYPE)); memset(B, 0, Nx * Ny * Nz * sizeof(TYPE));
@ -247,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++) { for (int ih = -Nhx; ih <= Nhx; ih++) {
int i2 = imfilter_index(i1 + ih, Nx, BCx); int i2 = imfilter_index(i1 + ih, Nx, BCx);
bool fixed = i2 == -1 || j2 == -1 || k2 == -1; 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; tmp += H[ijkh] * A2;
ijkh++; ijkh++;
} }
@ -260,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"); PROFILE_STOP("imfilter_3D");
} }
/******************************************************** /********************************************************
* Perform N-D filtering * * Perform N-D filtering *
********************************************************/ ********************************************************/
template <class TYPE> template <class TYPE>
Array<TYPE> imfilter::imfilter( const Array<TYPE>& A, Array<TYPE> imfilter::imfilter(const Array<TYPE> &A, const Array<TYPE> &H,
const Array<TYPE>& H, const std::vector<imfilter::BC>& BC, const TYPE X ) const std::vector<imfilter::BC> &BC,
{ const TYPE X) {
IMFILTER_ASSERT(A.ndim() == H.ndim()); IMFILTER_ASSERT(A.ndim() == H.ndim());
IMFILTER_ASSERT(A.ndim() == BC.size()); IMFILTER_ASSERT(A.ndim() == BC.size());
std::vector<size_t> Nh = H.size(); std::vector<size_t> Nh = H.size();
for (int d = 0; d < A.ndim(); d++) { for (int d = 0; d < A.ndim(); d++) {
Nh[d] = (H.size(d) - 1) / 2; 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; auto B = A;
if (A.ndim() == 1) { if (A.ndim() == 1) {
@ -281,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()); filter_direction(1, A.size(0), 1, Nh[0], H.data(), BC[0], X, B.data());
PROFILE_STOP("imfilter_1D"); PROFILE_STOP("imfilter_1D");
} else if (A.ndim() == 2) { } 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) { } else if (A.ndim() == 3) {
imfilter_3D( A.size(0), A.size(1), A.size(2), A.data(), imfilter_3D(A.size(0), A.size(1), A.size(2), A.data(), Nh[0], Nh[1],
Nh[0], Nh[1], Nh[2], H.data(), BC[0], BC[1], BC[2], X, B.data() ); Nh[2], H.data(), BC[0], BC[1], BC[2], X, B.data());
} else { } else {
IMFILTER_ERROR("Arbitrary dimension not yet supported"); IMFILTER_ERROR("Arbitrary dimension not yet supported");
} }
return B; return B;
} }
template <class TYPE> 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, 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)"); PROFILE_START("imfilter (lambda)");
IMFILTER_ASSERT(A.ndim() == Nh0.size()); IMFILTER_ASSERT(A.ndim() == Nh0.size());
IMFILTER_ASSERT(A.ndim() == BC0.size()); IMFILTER_ASSERT(A.ndim() == BC0.size());
@ -303,7 +294,8 @@ Array<TYPE> imfilter::imfilter( const Array<TYPE>& A, const std::vector<int>& Nh
Nh2[d] = 2 * Nh0[d] + 1; Nh2[d] = 2 * Nh0[d] + 1;
auto B = A; auto B = A;
Array<TYPE> data(Nh2); 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 N = A.size();
auto Nh = Nh0; auto Nh = Nh0;
auto BC = BC0; auto BC = BC0;
@ -320,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++) { for (int ih = -Nh[0]; ih <= Nh[0]; ih++) {
int i2 = imfilter_index(i1 + ih, N[0], BC[0]); int i2 = imfilter_index(i1 + ih, N[0], BC[0]);
bool fixed = i2 == -1 || j2 == -1 || k2 == -1; 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);
} }
} }
} }
@ -332,15 +325,13 @@ Array<TYPE> imfilter::imfilter( const Array<TYPE>& A, const std::vector<int>& Nh
return B; return B;
} }
/******************************************************** /********************************************************
* imfilter with separable filter functions * * imfilter with separable filter functions *
********************************************************/ ********************************************************/
template <class TYPE> template <class TYPE>
Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A, Array<TYPE> imfilter::imfilter_separable(
const std::vector<Array<TYPE>>& H, const Array<TYPE> &A, const std::vector<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"); PROFILE_START("imfilter_separable");
IMFILTER_ASSERT(A.ndim() == (int)H.size()); IMFILTER_ASSERT(A.ndim() == (int)H.size());
IMFILTER_ASSERT(A.ndim() == (int)boundary.size()); IMFILTER_ASSERT(A.ndim() == (int)boundary.size());
@ -348,7 +339,8 @@ Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A,
for (int d = 0; d < A.ndim(); d++) { for (int d = 0; d < A.ndim(); d++) {
IMFILTER_ASSERT(H[d].ndim() == 1); IMFILTER_ASSERT(H[d].ndim() == 1);
Nh[d] = (H[d].length() - 1) / 2; 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; auto B = A;
for (int d = 0; d < A.ndim(); d++) { for (int d = 0; d < A.ndim(); d++) {
@ -359,16 +351,17 @@ Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A,
Ns *= A.size(d2); Ns *= A.size(d2);
for (int d2 = d + 1; d2 < A.ndim(); d2++) for (int d2 = d + 1; d2 < A.ndim(); d2++)
Ne *= A.size(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"); PROFILE_STOP("imfilter_separable");
return B; return B;
} }
template <class TYPE> 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, 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)"); PROFILE_START("imfilter_separable (lambda)");
IMFILTER_ASSERT(A.ndim() == (int)boundary.size()); IMFILTER_ASSERT(A.ndim() == (int)boundary.size());
auto B = A; auto B = A;
@ -386,10 +379,10 @@ Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A, const std::vecto
return B; return B;
} }
template <class TYPE> 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, 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)"); PROFILE_START("imfilter_separable (function)");
IMFILTER_ASSERT(A.ndim() == (int)boundary.size()); IMFILTER_ASSERT(A.ndim() == (int)boundary.size());
auto B = A; auto B = A;
@ -406,5 +399,3 @@ Array<TYPE> imfilter::imfilter_separable( const Array<TYPE>& A, const std::vecto
PROFILE_STOP("imfilter_separable (function)"); PROFILE_STOP("imfilter_separable (function)");
return B; return B;
} }

View File

@ -1,7 +1,8 @@
#include <analysis/morphology.h> #include <analysis/morphology.h>
// Implementation of morphological opening routine // 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 // Fill in the phase ID values from neighboring processors
// This packs up the values that need to be sent from one processor to another // This packs up the values that need to be sent from one processor to another
int idx, n; 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 // Fill in the phase ID values from neighboring processors
// This unpacks the values once they have been recieved from neighbors // This unpacks the values once they have been recieved from neighbors
int idx, n; int idx, n;
@ -30,9 +32,7 @@ Morphology::Morphology(){
sendtag = recvtag = 1381; sendtag = recvtag = 1381;
} }
Morphology::~Morphology(){ Morphology::~Morphology() {}
}
void Morphology::Initialize(std::shared_ptr<Domain> Dm, DoubleArray &Distance) { void Morphology::Initialize(std::shared_ptr<Domain> Dm, DoubleArray &Distance) {
/* Loop over all faces and determine overlaps */ /* Loop over all faces and determine overlaps */
@ -89,7 +89,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
morphRadius.resize(recvLoc); morphRadius.resize(recvLoc);
//.............................. //..............................
/* send the morphological radius */ /* 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); Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_x(), sendtag + 0);
/* send the shift values */ /* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_X], recvCount, Dm->rank_X(), recvtag + 1); 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); morphRadius.resize(recvLoc);
//.............................. //..............................
/* send the morphological radius */ /* 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); Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_X(), sendtag + 0);
/* send the shift values */ /* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_x], recvCount, Dm->rank_x(), recvtag + 1); 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); morphRadius.resize(recvLoc);
//.............................. //..............................
/* send the morphological radius */ /* 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); Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_y(), sendtag + 0);
/* send the shift values */ /* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_Y], recvCount, Dm->rank_Y(), recvtag + 1); 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); morphRadius.resize(recvLoc);
//.............................. //..............................
/* send the morphological radius */ /* 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); Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_Y(), sendtag + 0);
/* send the shift values */ /* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_y], recvCount, Dm->rank_y(), recvtag + 1); 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); morphRadius.resize(recvLoc);
//.............................. //..............................
/* send the morphological radius */ /* 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); Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_z(), sendtag + 0);
/* send the shift values */ /* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_Z], recvCount, Dm->rank_Z(), recvtag + 1); 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); morphRadius.resize(recvLoc);
//.............................. //..............................
/* send the morphological radius */ /* 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); Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_Z(), sendtag + 0);
/* send the shift values */ /* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_z], recvCount, Dm->rank_z(), recvtag + 1); 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);
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 Nx = Dm->Nx;
int Ny = Dm->Ny; int Ny = Dm->Ny;
@ -369,28 +376,40 @@ int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const
localID[idx] = id[n]; localID[idx] = id[n];
} }
//printf("send x -- offset: %i, count: %i \n",sendOffset_x,sendCount_x); //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.Irecv(&nonlocalID[recvOffset_X], recvCount_X, Dm->rank_x(),
Dm->Comm.send(&localID[sendOffset_x],sendCount_x,Dm->rank_X(),sendtag+2); recvtag + 2);
Dm->Comm.send(&localID[sendOffset_x], sendCount_x, Dm->rank_X(),
sendtag + 2);
//printf("send X \n"); //printf("send X \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_x],recvCount_x,Dm->rank_X(),recvtag+3); Dm->Comm.Irecv(&nonlocalID[recvOffset_x], recvCount_x, Dm->rank_X(),
Dm->Comm.send(&localID[sendOffset_X],sendCount_X,Dm->rank_x(),sendtag+3); recvtag + 3);
Dm->Comm.send(&localID[sendOffset_X], sendCount_X, Dm->rank_x(),
sendtag + 3);
//printf("send y \n"); //printf("send y \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_Y],recvCount_Y,Dm->rank_y(),recvtag+4); Dm->Comm.Irecv(&nonlocalID[recvOffset_Y], recvCount_Y, Dm->rank_y(),
Dm->Comm.send(&localID[sendOffset_y],sendCount_y,Dm->rank_Y(),sendtag+4); recvtag + 4);
Dm->Comm.send(&localID[sendOffset_y], sendCount_y, Dm->rank_Y(),
sendtag + 4);
//printf("send Y \n"); //printf("send Y \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_y],recvCount_y,Dm->rank_Y(),recvtag+5); Dm->Comm.Irecv(&nonlocalID[recvOffset_y], recvCount_y, Dm->rank_Y(),
Dm->Comm.send(&localID[sendOffset_Y],sendCount_Y,Dm->rank_y(),sendtag+5); recvtag + 5);
Dm->Comm.send(&localID[sendOffset_Y], sendCount_Y, Dm->rank_y(),
sendtag + 5);
//printf("send z \n"); //printf("send z \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_Z],recvCount_Z,Dm->rank_z(),recvtag+6); Dm->Comm.Irecv(&nonlocalID[recvOffset_Z], recvCount_Z, Dm->rank_z(),
Dm->Comm.send(&localID[sendOffset_z],sendCount_z,Dm->rank_Z(),sendtag+6); recvtag + 6);
Dm->Comm.send(&localID[sendOffset_z], sendCount_z, Dm->rank_Z(),
sendtag + 6);
//printf("send Z \n"); //printf("send Z \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_z],recvCount_z,Dm->rank_Z(),recvtag+7); Dm->Comm.Irecv(&nonlocalID[recvOffset_z], recvCount_z, Dm->rank_Z(),
Dm->Comm.send(&localID[sendOffset_Z],sendCount_Z,Dm->rank_z(),sendtag+7); recvtag + 7);
Dm->Comm.send(&localID[sendOffset_Z], sendCount_Z, Dm->rank_z(),
sendtag + 7);
for (int idx = 0; idx < recvCount; idx++) { for (int idx = 0; idx < recvCount; idx++) {
double radius = morphRadius[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 (jj = jmin; jj < jmax; jj++) {
for (ii = imin; ii < imax; ii++) { for (ii = imin; ii < imax; ii++) {
int nn = kk * Nx * Ny + jj * Nx + 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) { if (id[nn] == ErodeLabel && dsq <= radius * radius) {
LocalNumber += 1.0; LocalNumber += 1.0;
id[nn] = NewLabel; 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 // 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 // VoidFraction is the the empty space where the object inst
// id is a labeled map // 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++) { for (int i = 1; i < nx - 1; i++) {
n = k * nx * ny + j * nx + i; n = k * nx * ny + j * nx + i;
// extract maximum distance for critical radius // 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) { if (id[n] == ErodeLabel) {
count += 1.0; count += 1.0;
//id[n] = 2; //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 // total Global is the number of nodes in the pore-space
totalGlobal = Dm->Comm.sumReduce(count); totalGlobal = Dm->Comm.sumReduce(count);
maxdistGlobal = Dm->Comm.sumReduce(maxdist); 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; double volume_fraction = totalGlobal / volume;
if (rank==0) printf("Volume fraction for morphological opening: %f \n",volume_fraction); if (rank == 0)
if (rank==0) printf("Maximum pore size: %f \n",maxdistGlobal); 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 final_void_fraction = volume_fraction; //initialize
int ii, jj, kk; int ii, jj, kk;
@ -496,8 +524,7 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
int numTry = 0; int numTry = 0;
int maxTry = 100; int maxTry = 100;
while (void_fraction_new > VoidFraction && numTry < maxTry) while (void_fraction_new > VoidFraction && numTry < maxTry) {
{
numTry++; numTry++;
void_fraction_diff_old = void_fraction_diff_new; void_fraction_diff_old = void_fraction_diff_new;
void_fraction_old = void_fraction_new; void_fraction_old = void_fraction_new;
@ -507,7 +534,9 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
numTry = maxTry; numTry = maxTry;
} }
int Window = round(Rcrit_new); 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 // and sw<Sw will be immediately broken
double LocalNumber = 0.f; double LocalNumber = 0.f;
for (int k = 0; k < Nz; k++) { 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 (jj = jmin; jj < jmax; jj++) {
for (ii = imin; ii < imax; ii++) { for (ii = imin; ii < imax; ii++) {
int nn = kk * nx * ny + jj * nx + 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) +
if (id[nn] == ErodeLabel && dsq <= Rcrit_new*Rcrit_new){ (jj - j) * (jj - j) +
(kk - k) * (kk - k));
if (id[nn] == ErodeLabel &&
dsq <= Rcrit_new * Rcrit_new) {
LocalNumber += 1.0; LocalNumber += 1.0;
id[nn] = NewLabel; id[nn] = NewLabel;
} }
} }
} }
} }
} }
// move on // 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 void fraction =%f\n", void_fraction_new);
printf("Final critical radius=%f\n", Rcrit_new); printf("Final critical radius=%f\n", Rcrit_new);
} }
} } else {
else{
final_void_fraction = void_fraction_old; final_void_fraction = void_fraction_old;
if (rank == 0) { if (rank == 0) {
printf("Final void fraction=%f\n", void_fraction_old); 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; 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 // 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 // VoidFraction is the the empty space where the object inst
// id is a labeled map // 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); DoubleArray phase(nx, ny, nz);
IntArray phase_label(nx, ny, nz); IntArray phase_label(nx, ny, nz);
Array<char> ID(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; Morphology Structure;
Structure.Initialize(Dm, SignDist); 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++) { for (int i = 1; i < nx - 1; i++) {
n = k * nx * ny + j * nx + i; n = k * nx * ny + j * nx + i;
// extract maximum distance for critical radius // 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) { if (SignDist(i, j, k) > 0.0) {
count += 1.0; count += 1.0;
id[n] = ErodeLabel; 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 // total Global is the number of nodes in the pore-space
totalGlobal = Dm->Comm.sumReduce(count); totalGlobal = Dm->Comm.sumReduce(count);
maxdistGlobal = Dm->Comm.sumReduce(maxdist); 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; double volume_fraction = totalGlobal / volume;
if (rank==0) printf("Volume fraction for morphological opening: %f \n",volume_fraction); if (rank == 0)
if (rank==0) printf("Maximum pore size: %f \n",maxdistGlobal); 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 ii, jj, kk;
int imin, jmin, kmin, imax, jmax, kmax; 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"); FILE *DRAIN = fopen("morphdrain.csv", "w");
fprintf(DRAIN, "sw radius\n"); 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_diff_old = void_fraction_diff_new;
void_fraction_old = void_fraction_new; void_fraction_old = void_fraction_new;
Rcrit_old = Rcrit_new; Rcrit_old = Rcrit_new;
Rcrit_new -= deltaR * Rcrit_old; Rcrit_new -= deltaR * Rcrit_old;
int Window = round(Rcrit_new); 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 // and sw<Sw will be immediately broken
double LocalNumber = 0.f; double LocalNumber = 0.f;
for (int k = 1; k < Nz - 1; k++) { 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 (kk = kmin; kk < kmax; kk++) {
for (jj = jmin; jj < jmax; jj++) { for (jj = jmin; jj < jmax; jj++) {
for (ii = imin; ii < imax; ii++) { for (ii = imin; ii < imax; ii++) {
double dsq = double((ii-i)*(ii-i)+(jj-j)*(jj-j)+(kk-k)*(kk-k)); double dsq = double((ii - i) * (ii - i) +
if (ID(ii,jj,kk) == ErodeLabel && dsq <= (Rcrit_new+1)*(Rcrit_new+1)){ (jj - j) * (jj - j) +
(kk - k) * (kk - k));
if (ID(ii, jj, kk) == ErodeLabel &&
dsq <=
(Rcrit_new + 1) * (Rcrit_new + 1)) {
LocalNumber += 1.0; LocalNumber += 1.0;
//id[nn]=1; //id[nn]=1;
ID(ii, jj, kk) = NewLabel; 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++) { for (int i = 0; i < nx; i++) {
if (ID(i, j, k) == NewLabel) { if (ID(i, j, k) == NewLabel) {
phase(i, j, k) = 1.0; phase(i, j, k) = 1.0;
} } else
else
phase(i, j, k) = -1.0; phase(i, j, k) = -1.0;
} }
} }
} }
// Extract only the connected part of NWP // Extract only the connected part of NWP
double vF=0.0; double vS=0.0; double vF = 0.0;
ComputeGlobalBlobIDs(nx-2,ny-2,nz-2,Dm->rank_info,phase,SignDist,vF,vS,phase_label,Dm->Comm); 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(); Dm->Comm.barrier();
for (int k = 0; k < nz; k++) { 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 void fraction =%f\n", void_fraction_new);
printf("Final critical radius=%f\n", Rcrit_new); printf("Final critical radius=%f\n", Rcrit_new);
} }
} } else {
else{
final_void_fraction = void_fraction_old; final_void_fraction = void_fraction_old;
if (rank == 0) { if (rank == 0) {
printf("Final void fraction=%f\n", void_fraction_old); 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 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 Nx = Dm->Nx;
int Ny = Dm->Ny; int Ny = Dm->Ny;
int Nz = Dm->Nz; int Nz = Dm->Nz;
@ -815,14 +858,17 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
// Estimate morph_delta // Estimate morph_delta
double morph_delta = 0.0; double morph_delta = 0.0;
if (TargetGrowth > 0.0) morph_delta = 0.1; if (TargetGrowth > 0.0)
else morph_delta = -0.1; morph_delta = 0.1;
else
morph_delta = -0.1;
double morph_delta_previous = 0.0; double morph_delta_previous = 0.0;
double GrowthEstimate = 0.0; double GrowthEstimate = 0.0;
double GrowthPrevious = 0.0; double GrowthPrevious = 0.0;
int COUNT_FOR_LOOP = 0; int COUNT_FOR_LOOP = 0;
double ERROR = 100.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) { while (ERROR > 0.01 && COUNT_FOR_LOOP < 10) {
COUNT_FOR_LOOP++; COUNT_FOR_LOOP++;
count = 0.0; count = 0.0;
@ -832,9 +878,11 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
for (int i = 1; i < Nx - 1; i++) { for (int i = 1; i < Nx - 1; i++) {
double walldist = BoundaryDist(i, j, k); double walldist = BoundaryDist(i, j, k);
//double wallweight = 1.0 / (1+exp(-5.f*(walldist-1.f))); //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; //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) { if (Dist(i, j, k) - wallweight * morph_delta < 0.0) {
count += 1.0; count += 1.0;
@ -847,15 +895,20 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
GrowthEstimate = count - count_original; GrowthEstimate = count - count_original;
ERROR = fabs((GrowthEstimate - TargetGrowth) / TargetGrowth); 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 // Now adjust morph_delta
if (fabs(GrowthEstimate - GrowthPrevious) > 0.0) { 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; GrowthPrevious = GrowthEstimate;
morph_delta_previous = morph_delta; morph_delta_previous = morph_delta;
morph_delta += step_size; 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); //MAX_DISPLACEMENT *= max(TargetGrowth/GrowthEstimate,1.25);
@ -865,8 +918,7 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
morph_delta = 3.0; morph_delta = 3.0;
COUNT_FOR_LOOP = 100; // exit loop if displacement is too large COUNT_FOR_LOOP = 100; // exit loop if displacement is too large
} }
} } else {
else{
// object is shrinking // object is shrinking
if (MAX_DISPLACEMENT > 1.0) { if (MAX_DISPLACEMENT > 1.0) {
morph_delta = -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; count = 0.0;
for (int k = 1; k < Nz - 1; k++) { 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 walldist = BoundaryDist(i, j, k);
//double wallweight = 1.0 / (1+exp(-5.f*(walldist-1.f))); //double wallweight = 1.0 / (1+exp(-5.f*(walldist-1.f)));
//wallweight = 1.0; //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; 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; return count;
} }

View File

@ -3,9 +3,14 @@
#include "common/Domain.h" #include "common/Domain.h"
#include "analysis/runAnalysis.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 MorphOpen(DoubleArray &SignDist, signed char *id,
double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction); 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); 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 #ifndef MORPHOLOGY_INC
#define MORPHOLOGY_INC #define MORPHOLOGY_INC
@ -41,7 +46,8 @@ public:
* @param ErodeLabel label to erode based on morphological operation * @param ErodeLabel label to erode based on morphological operation
* @param NewLabel label to assign 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 * data structures to store non-local morphological information
@ -58,27 +64,39 @@ private:
//...................................................................................... //......................................................................................
int sendCount, recvCount; int sendCount, recvCount;
//...................................................................................... //......................................................................................
int sendOffset_x, sendOffset_y, sendOffset_z, sendOffset_X, sendOffset_Y, sendOffset_Z; int sendOffset_x, sendOffset_y, sendOffset_z, sendOffset_X, sendOffset_Y,
int sendOffset_xy, sendOffset_yz, sendOffset_xz, sendOffset_Xy, sendOffset_Yz, sendOffset_xZ; 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_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 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_x, recvOffset_y, recvOffset_z, recvOffset_X, recvOffset_Y,
int recvOffset_xy, recvOffset_yz, recvOffset_xz, recvOffset_Xy, recvOffset_Yz, recvOffset_xZ; 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_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 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_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y,
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz, sendCount_xZ; 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_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 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_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y,
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz, recvCount_xZ; 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_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;
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 // Communication buffers
signed char *sendID_x, *sendID_y, *sendID_z, *sendID_X, *sendID_Y, *sendID_Z; signed char *sendID_x, *sendID_y, *sendID_z, *sendID_X, *sendID_Y,
signed char *sendID_xy, *sendID_yz, *sendID_xz, *sendID_Xy, *sendID_Yz, *sendID_xZ; *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,
signed char *recvID_x, *recvID_y, *recvID_z, *recvID_X, *recvID_Y, *recvID_Z; *sendID_xZ;
signed char *recvID_xy, *recvID_yz, *recvID_xz, *recvID_Xy, *recvID_Yz, *recvID_xZ; signed char *sendID_xY, *sendID_yZ, *sendID_Xz, *sendID_XY, *sendID_YZ,
signed char *recvID_xY, *recvID_yZ, *recvID_Xz, *recvID_XY, *recvID_YZ, *recvID_XZ; *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 #endif

File diff suppressed because it is too large Load Diff

View File

@ -28,39 +28,32 @@
#include "ProfilerApp.h" #include "ProfilerApp.h"
AnalysisType &operator|=(AnalysisType &lhs, AnalysisType rhs) {
AnalysisType &operator|=( AnalysisType &lhs, AnalysisType rhs ) lhs = static_cast<AnalysisType>(
{ static_cast<std::underlying_type<AnalysisType>::type>(lhs) |
lhs = static_cast<AnalysisType>( static_cast<std::underlying_type<AnalysisType>::type>( lhs ) |
static_cast<std::underlying_type<AnalysisType>::type>(rhs)); static_cast<std::underlying_type<AnalysisType>::type>(rhs));
return lhs; return lhs;
} }
bool matches( AnalysisType x, AnalysisType y ) bool matches(AnalysisType x, AnalysisType y) {
{
return (static_cast<std::underlying_type<AnalysisType>::type>(x) & return (static_cast<std::underlying_type<AnalysisType>::type>(x) &
static_cast<std::underlying_type<AnalysisType>::type>(y)) != 0; static_cast<std::underlying_type<AnalysisType>::type>(y)) != 0;
} }
// Create a shared_ptr to an array of values // Create a shared_ptr to an array of values
template <class TYPE> template <class TYPE>
static inline std::shared_ptr<TYPE> make_shared_array( size_t N ) static inline std::shared_ptr<TYPE> make_shared_array(size_t N) {
{ return std::shared_ptr<TYPE>(new TYPE[N],
return std::shared_ptr<TYPE>( new TYPE[N], []( const TYPE *p ) { delete[] p; } ); [](const TYPE *p) { delete[] p; });
} }
// Helper class to write the restart file from a seperate thread // Helper class to write the restart file from a seperate thread
class WriteRestartWorkItem : public ThreadPool::WorkItemRet<void> class WriteRestartWorkItem : public ThreadPool::WorkItemRet<void> {
{
public: 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_) std::shared_ptr<double> cfq_, int N_)
: filename( filename_ ), cfq( cfq_ ), cDen( cDen_ ), N( N_ ) : filename(filename_), cfq(cfq_), cDen(cDen_), N(N_) {}
{ virtual void run() {
}
virtual void run()
{
PROFILE_START("Save Checkpoint", 1); PROFILE_START("Save Checkpoint", 1);
double value; double value;
ofstream File(filename, ios::binary); ofstream File(filename, ios::binary);
@ -89,42 +82,32 @@ private:
const int N; const int N;
}; };
// Helper class to compute the blob ids // Helper class to compute the blob ids
typedef std::shared_ptr<std::pair<int, IntArray>> BlobIDstruct; typedef std::shared_ptr<std::pair<int, IntArray>> BlobIDstruct;
typedef std::shared_ptr<std::vector<BlobIDType>> BlobIDList; typedef std::shared_ptr<std::vector<BlobIDType>> BlobIDList;
static const std::string id_map_filename = "lbpm_id_map.txt"; static const std::string id_map_filename = "lbpm_id_map.txt";
class BlobIdentificationWorkItem1 : public ThreadPool::WorkItemRet<void> class BlobIdentificationWorkItem1 : public ThreadPool::WorkItemRet<void> {
{
public: public:
BlobIdentificationWorkItem1(int timestep_, int Nx_, int Ny_, int Nz_, BlobIdentificationWorkItem1(int timestep_, int Nx_, int Ny_, int Nz_,
const RankInfoStruct &rank_info_, std::shared_ptr<const DoubleArray> phase_, const RankInfoStruct &rank_info_,
const DoubleArray &dist_, BlobIDstruct last_id_, BlobIDstruct new_index_, std::shared_ptr<const DoubleArray> phase_,
BlobIDstruct new_id_, BlobIDList new_list_, runAnalysis::commWrapper &&comm_ ) const DoubleArray &dist_, BlobIDstruct last_id_,
: timestep( timestep_ ), BlobIDstruct new_index_, BlobIDstruct new_id_,
Nx( Nx_ ), BlobIDList new_list_,
Ny( Ny_ ), runAnalysis::commWrapper &&comm_)
Nz( Nz_ ), : timestep(timestep_), Nx(Nx_), Ny(Ny_), Nz(Nz_), rank_info(rank_info_),
rank_info( rank_info_ ), phase(phase_), dist(dist_), last_id(last_id_), new_index(new_index_),
phase( phase_ ), new_id(new_id_), new_list(new_list_), comm(std::move(comm_)) {}
dist( dist_ ),
last_id( last_id_ ),
new_index( new_index_ ),
new_id( new_id_ ),
new_list( new_list_ ),
comm( std::move( comm_ ) )
{
}
~BlobIdentificationWorkItem1() {} ~BlobIdentificationWorkItem1() {}
virtual void run() virtual void run() {
{
// Compute the global blob id and compare to the previous version // Compute the global blob id and compare to the previous version
PROFILE_START("Identify blobs", 1); PROFILE_START("Identify blobs", 1);
double vF = 0.0; double vF = 0.0;
double vS = -1.0; // one voxel buffer region around solid double vS = -1.0; // one voxel buffer region around solid
IntArray &ids = new_index->second; IntArray &ids = new_index->second;
new_index->first = ComputeGlobalBlobIDs( new_index->first =
Nx - 2, Ny - 2, Nz - 2, rank_info, *phase, dist, vF, vS, ids, comm.comm ); ComputeGlobalBlobIDs(Nx - 2, Ny - 2, Nz - 2, rank_info, *phase,
dist, vF, vS, ids, comm.comm);
PROFILE_STOP("Identify blobs", 1); PROFILE_STOP("Identify blobs", 1);
} }
@ -139,30 +122,20 @@ private:
BlobIDList new_list; BlobIDList new_list;
runAnalysis::commWrapper comm; runAnalysis::commWrapper comm;
}; };
class BlobIdentificationWorkItem2 : public ThreadPool::WorkItemRet<void> class BlobIdentificationWorkItem2 : public ThreadPool::WorkItemRet<void> {
{
public: public:
BlobIdentificationWorkItem2(int timestep_, int Nx_, int Ny_, int Nz_, BlobIdentificationWorkItem2(int timestep_, int Nx_, int Ny_, int Nz_,
const RankInfoStruct &rank_info_, std::shared_ptr<const DoubleArray> phase_, const RankInfoStruct &rank_info_,
const DoubleArray &dist_, BlobIDstruct last_id_, BlobIDstruct new_index_, std::shared_ptr<const DoubleArray> phase_,
BlobIDstruct new_id_, BlobIDList new_list_, runAnalysis::commWrapper &&comm_ ) const DoubleArray &dist_, BlobIDstruct last_id_,
: timestep( timestep_ ), BlobIDstruct new_index_, BlobIDstruct new_id_,
Nx( Nx_ ), BlobIDList new_list_,
Ny( Ny_ ), runAnalysis::commWrapper &&comm_)
Nz( Nz_ ), : timestep(timestep_), Nx(Nx_), Ny(Ny_), Nz(Nz_), rank_info(rank_info_),
rank_info( rank_info_ ), phase(phase_), dist(dist_), last_id(last_id_), new_index(new_index_),
phase( phase_ ), new_id(new_id_), new_list(new_list_), comm(std::move(comm_)) {}
dist( dist_ ),
last_id( last_id_ ),
new_index( new_index_ ),
new_id( new_id_ ),
new_list( new_list_ ),
comm( std::move( comm_ ) )
{
}
~BlobIdentificationWorkItem2() {} ~BlobIdentificationWorkItem2() {}
virtual void run() virtual void run() {
{
// Compute the global blob id and compare to the previous version // Compute the global blob id and compare to the previous version
PROFILE_START("Identify blobs maps", 1); PROFILE_START("Identify blobs maps", 1);
const IntArray &ids = new_index->second; const IntArray &ids = new_index->second;
@ -172,7 +145,8 @@ public:
if (last_id.get() != NULL) { if (last_id.get() != NULL) {
// Compute the timestep-timestep map // Compute the timestep-timestep map
const IntArray &old_ids = last_id->second; 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 // Renumber the current timestep's ids
getNewIDs(map, max_id, *new_list); getNewIDs(map, max_id, *new_list);
renumberIDs(*new_list, new_id->second); renumberIDs(*new_list, new_id->second);
@ -198,25 +172,18 @@ private:
runAnalysis::commWrapper comm; runAnalysis::commWrapper comm;
}; };
// Helper class to write the vis file from a thread // Helper class to write the vis file from a thread
class WriteVisWorkItem : public ThreadPool::WorkItemRet<void> class WriteVisWorkItem : public ThreadPool::WorkItemRet<void> {
{
public: public:
WriteVisWorkItem(int timestep_, std::vector<IO::MeshDataStruct> &visData_, 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_) runAnalysis::commWrapper &&comm_)
: timestep( timestep_ ), : timestep(timestep_), visData(visData_), Averages(Avgerages_),
visData( visData_ ), n(std::move(n_)), rank_info(std::move(rank_info_)),
Averages( Avgerages_ ), comm(std::move(comm_)) {}
n( std::move( n_ ) ),
rank_info( std::move( rank_info_ ) ),
comm( std::move( comm_ ) )
{
}
~WriteVisWorkItem() {} ~WriteVisWorkItem() {}
virtual void run() virtual void run() {
{
PROFILE_START("Save Vis", 1); PROFILE_START("Save Vis", 1);
fillHalo<double> fillData(comm.comm, rank_info, n, {1, 1, 1}, 0, 1); fillHalo<double> fillData(comm.comm, rank_info, n, {1, 1, 1}, 0, 1);
@ -262,24 +229,17 @@ private:
}; };
// Helper class to write the vis file from a thread // Helper class to write the vis file from a thread
class IOWorkItem : public ThreadPool::WorkItemRet<void> class IOWorkItem : public ThreadPool::WorkItemRet<void> {
{
public: public:
IOWorkItem(int timestep_, std::shared_ptr<Database> input_db_, IOWorkItem(int timestep_, std::shared_ptr<Database> input_db_,
std::vector<IO::MeshDataStruct> &visData_, SubPhase &Averages_, std::array<int, 3> n_, std::vector<IO::MeshDataStruct> &visData_, SubPhase &Averages_,
RankInfoStruct rank_info_, runAnalysis::commWrapper &&comm_ ) std::array<int, 3> n_, RankInfoStruct rank_info_,
: timestep( timestep_ ), runAnalysis::commWrapper &&comm_)
input_db( input_db_ ), : timestep(timestep_), input_db(input_db_), visData(visData_),
visData( visData_ ), Averages(Averages_), n(std::move(n_)),
Averages( Averages_ ), rank_info(std::move(rank_info_)), comm(std::move(comm_)) {}
n( std::move( n_ ) ),
rank_info( std::move( rank_info_ ) ),
comm( std::move( comm_ ) )
{
}
~IOWorkItem() {} ~IOWorkItem() {}
virtual void run() virtual void run() {
{
PROFILE_START("Save Vis", 1); PROFILE_START("Save Vis", 1);
auto color_db = input_db->getDatabase("Color"); auto color_db = input_db->getDatabase("Color");
@ -353,25 +313,16 @@ private:
runAnalysis::commWrapper comm; runAnalysis::commWrapper comm;
}; };
// Helper class to run the analysis from within a thread // Helper class to run the analysis from within a thread
// Note: Averages will be modified after the constructor is called // Note: Averages will be modified after the constructor is called
class AnalysisWorkItem : public ThreadPool::WorkItemRet<void> class AnalysisWorkItem : public ThreadPool::WorkItemRet<void> {
{
public: public:
AnalysisWorkItem( AnalysisType type_, int timestep_, TwoPhase &Averages_, BlobIDstruct ids, AnalysisWorkItem(AnalysisType type_, int timestep_, TwoPhase &Averages_,
BlobIDList id_list_, double beta_ ) BlobIDstruct ids, BlobIDList id_list_, double beta_)
: type( type_ ), : type(type_), timestep(timestep_), Averages(Averages_), blob_ids(ids),
timestep( timestep_ ), id_list(id_list_), beta(beta_) {}
Averages( Averages_ ),
blob_ids( ids ),
id_list( id_list_ ),
beta( beta_ )
{
}
~AnalysisWorkItem() {} ~AnalysisWorkItem() {}
virtual void run() virtual void run() {
{
Averages.NumberComponents_NWP = blob_ids->first; Averages.NumberComponents_NWP = blob_ids->first;
Averages.Label_NWP = blob_ids->second; Averages.Label_NWP = blob_ids->second;
Averages.Label_NWP_map = *id_list; Averages.Label_NWP_map = *id_list;
@ -385,8 +336,10 @@ public:
Averages.Initialize(); Averages.Initialize();
Averages.ComputeDelPhi(); Averages.ComputeDelPhi();
Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn); Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn);
Averages.ColorToSignedDistance( beta, Averages.Phase_tminus, Averages.Phase_tminus ); Averages.ColorToSignedDistance(beta, Averages.Phase_tminus,
Averages.ColorToSignedDistance( beta, Averages.Phase_tplus, Averages.Phase_tplus ); Averages.Phase_tminus);
Averages.ColorToSignedDistance(beta, Averages.Phase_tplus,
Averages.Phase_tplus);
Averages.UpdateMeshValues(); Averages.UpdateMeshValues();
Averages.ComputeLocal(); Averages.ComputeLocal();
Averages.Reduce(); Averages.Reduce();
@ -409,23 +362,14 @@ private:
double beta; double beta;
}; };
class TCATWorkItem : public ThreadPool::WorkItemRet<void> {
class TCATWorkItem : public ThreadPool::WorkItemRet<void>
{
public: public:
TCATWorkItem( AnalysisType type_, int timestep_, TwoPhase &Averages_, BlobIDstruct ids, TCATWorkItem(AnalysisType type_, int timestep_, TwoPhase &Averages_,
BlobIDList id_list_, double beta_ ) BlobIDstruct ids, BlobIDList id_list_, double beta_)
: type( type_ ), : type(type_), timestep(timestep_), Averages(Averages_), blob_ids(ids),
timestep( timestep_ ), id_list(id_list_), beta(beta_) {}
Averages( Averages_ ),
blob_ids( ids ),
id_list( id_list_ ),
beta( beta_ )
{
}
~TCATWorkItem() {} ~TCATWorkItem() {}
virtual void run() virtual void run() {
{
Averages.NumberComponents_NWP = blob_ids->first; Averages.NumberComponents_NWP = blob_ids->first;
Averages.Label_NWP = blob_ids->second; Averages.Label_NWP = blob_ids->second;
Averages.Label_NWP_map = *id_list; Averages.Label_NWP_map = *id_list;
@ -439,8 +383,10 @@ public:
Averages.Initialize(); Averages.Initialize();
Averages.ComputeDelPhi(); Averages.ComputeDelPhi();
Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn); Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn);
Averages.ColorToSignedDistance( beta, Averages.Phase_tminus, Averages.Phase_tminus ); Averages.ColorToSignedDistance(beta, Averages.Phase_tminus,
Averages.ColorToSignedDistance( beta, Averages.Phase_tplus, Averages.Phase_tplus ); Averages.Phase_tminus);
Averages.ColorToSignedDistance(beta, Averages.Phase_tplus,
Averages.Phase_tplus);
Averages.UpdateMeshValues(); Averages.UpdateMeshValues();
Averages.ComputeLocal(); Averages.ComputeLocal();
Averages.Reduce(); Averages.Reduce();
@ -459,23 +405,15 @@ private:
double beta; double beta;
}; };
class GanglionTrackingWorkItem : public ThreadPool::WorkItemRet<void> {
class GanglionTrackingWorkItem : public ThreadPool::WorkItemRet<void>
{
public: public:
GanglionTrackingWorkItem( AnalysisType type_, int timestep_, TwoPhase &Averages_, GanglionTrackingWorkItem(AnalysisType type_, int timestep_,
BlobIDstruct ids, BlobIDList id_list_, double beta_ ) TwoPhase &Averages_, BlobIDstruct ids,
: type( type_ ), BlobIDList id_list_, double beta_)
timestep( timestep_ ), : type(type_), timestep(timestep_), Averages(Averages_), blob_ids(ids),
Averages( Averages_ ), id_list(id_list_), beta(beta_) {}
blob_ids( ids ),
id_list( id_list_ ),
beta( beta_ )
{
}
~GanglionTrackingWorkItem() {} ~GanglionTrackingWorkItem() {}
virtual void run() virtual void run() {
{
Averages.NumberComponents_NWP = blob_ids->first; Averages.NumberComponents_NWP = blob_ids->first;
Averages.Label_NWP = blob_ids->second; Averages.Label_NWP = blob_ids->second;
Averages.Label_NWP_map = *id_list; Averages.Label_NWP_map = *id_list;
@ -489,8 +427,10 @@ public:
Averages.Initialize(); Averages.Initialize();
Averages.ComputeDelPhi(); Averages.ComputeDelPhi();
Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn); Averages.ColorToSignedDistance(beta, Averages.Phase, Averages.SDn);
Averages.ColorToSignedDistance( beta, Averages.Phase_tminus, Averages.Phase_tminus ); Averages.ColorToSignedDistance(beta, Averages.Phase_tminus,
Averages.ColorToSignedDistance( beta, Averages.Phase_tplus, Averages.Phase_tplus ); Averages.Phase_tminus);
Averages.ColorToSignedDistance(beta, Averages.Phase_tplus,
Averages.Phase_tplus);
Averages.UpdateMeshValues(); Averages.UpdateMeshValues();
Averages.ComponentAverages(); Averages.ComponentAverages();
Averages.SortBlobs(); Averages.SortBlobs();
@ -509,17 +449,12 @@ private:
double beta; double beta;
}; };
class BasicWorkItem : public ThreadPool::WorkItemRet<void> {
class BasicWorkItem : public ThreadPool::WorkItemRet<void>
{
public: public:
BasicWorkItem(AnalysisType type_, int timestep_, SubPhase &Averages_) BasicWorkItem(AnalysisType type_, int timestep_, SubPhase &Averages_)
: type( type_ ), timestep( timestep_ ), Averages( Averages_ ) : type(type_), timestep(timestep_), Averages(Averages_) {}
{
}
~BasicWorkItem() {} ~BasicWorkItem() {}
virtual void run() virtual void run() {
{
if (matches(type, AnalysisType::CopyPhaseIndicator)) { if (matches(type, AnalysisType::CopyPhaseIndicator)) {
// Averages.ColorToSignedDistance(beta,Averages.Phase,Averages.Phase_tplus); // Averages.ColorToSignedDistance(beta,Averages.Phase,Averages.Phase_tplus);
@ -539,16 +474,12 @@ private:
double beta; double beta;
}; };
class SubphaseWorkItem : public ThreadPool::WorkItemRet<void> class SubphaseWorkItem : public ThreadPool::WorkItemRet<void> {
{
public: public:
SubphaseWorkItem(AnalysisType type_, int timestep_, SubPhase &Averages_) SubphaseWorkItem(AnalysisType type_, int timestep_, SubPhase &Averages_)
: type( type_ ), timestep( timestep_ ), Averages( Averages_ ) : type(type_), timestep(timestep_), Averages(Averages_) {}
{
}
~SubphaseWorkItem() {} ~SubphaseWorkItem() {}
virtual void run() virtual void run() {
{
PROFILE_START("Compute subphase", 1); PROFILE_START("Compute subphase", 1);
Averages.Full(); Averages.Full();
@ -564,29 +495,23 @@ private:
double beta; double beta;
}; };
/****************************************************************** /******************************************************************
* MPI comm wrapper for use with analysis * * MPI comm wrapper for use with analysis *
******************************************************************/ ******************************************************************/
runAnalysis::commWrapper::commWrapper( runAnalysis::commWrapper::commWrapper(int tag_, const Utilities::MPI &comm_,
int tag_, const Utilities::MPI &comm_, runAnalysis *analysis_ ) runAnalysis *analysis_)
: comm( comm_ ), tag( tag_ ), analysis( analysis_ ) : comm(comm_), tag(tag_), analysis(analysis_) {}
{
}
runAnalysis::commWrapper::commWrapper(commWrapper &&rhs) 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; rhs.tag = -1;
} }
runAnalysis::commWrapper::~commWrapper() runAnalysis::commWrapper::~commWrapper() {
{
if (tag == -1) if (tag == -1)
return; return;
comm.barrier(); comm.barrier();
analysis->d_comm_used[tag] = false; analysis->d_comm_used[tag] = false;
} }
runAnalysis::commWrapper runAnalysis::getComm() runAnalysis::commWrapper runAnalysis::getComm() {
{
// Get a tag from root // Get a tag from root
int tag = -1; int tag = -1;
if (d_rank == 0) { if (d_rank == 0) {
@ -606,20 +531,16 @@ runAnalysis::commWrapper runAnalysis::getComm()
return commWrapper(tag, d_comms[tag], this); return commWrapper(tag, d_comms[tag], this);
} }
/****************************************************************** /******************************************************************
* Constructor/Destructors * * Constructor/Destructors *
******************************************************************/ ******************************************************************/
runAnalysis::runAnalysis( std::shared_ptr<Database> input_db, const RankInfoStruct &rank_info, runAnalysis::runAnalysis(std::shared_ptr<Database> input_db,
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm, std::shared_ptr<Domain> Dm, int Np, const RankInfoStruct &rank_info,
bool Regular, IntArray Map ) std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm,
: d_Np( Np ), std::shared_ptr<Domain> Dm, int Np, bool Regular,
d_regular( Regular ), IntArray Map)
d_rank_info( rank_info ), : d_Np(Np), d_regular(Regular), d_rank_info(rank_info), d_Map(Map),
d_Map( Map ), d_comm(Dm->Comm.dup()), d_ScaLBL_Comm(ScaLBL_Comm) {
d_comm( Dm->Comm.dup() ),
d_ScaLBL_Comm( ScaLBL_Comm )
{
auto db = input_db->getDatabase("Analysis"); auto db = input_db->getDatabase("Analysis");
auto vis_db = input_db->getDatabase("Visualization"); auto vis_db = input_db->getDatabase("Visualization");
@ -655,13 +576,14 @@ runAnalysis::runAnalysis( std::shared_ptr<Database> input_db, const RankInfoStru
d_visualization_interval = db->getScalar<int>("visualization_interval"); d_visualization_interval = db->getScalar<int>("visualization_interval");
} }
if (db->keyExists("subphase_analysis_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_restartFile = restart_file + "." + rankString;
d_rank = d_comm.getRank(); d_rank = d_comm.getRank();
writeIDMap(ID_map_struct(), 0, id_map_filename); writeIDMap(ID_map_struct(), 0, id_map_filename);
@ -743,7 +665,6 @@ runAnalysis::runAnalysis( std::shared_ptr<Database> input_db, const RankInfoStru
d_meshData[0].vars.push_back(BlobIDVar); d_meshData[0].vars.push_back(BlobIDVar);
} }
// Initialize the comms // Initialize the comms
for (int i = 0; i < 1024; i++) for (int i = 0; i < 1024; i++)
d_comm_used[i] = false; d_comm_used[i] = false;
@ -800,10 +721,12 @@ runAnalysis::runAnalysis( ScaLBL_ColorModel &ColorModel)
d_visualization_interval = db->getScalar<int>("visualization_interval"); d_visualization_interval = db->getScalar<int>("visualization_interval");
} }
if (db->keyExists("subphase_analysis_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_restartFile = restart_file + "." + rankString;
d_rank = d_comm.getRank(); d_rank = d_comm.getRank();
@ -819,7 +742,8 @@ runAnalysis::runAnalysis( ScaLBL_ColorModel &ColorModel)
d_meshData[0].meshName = "domain"; d_meshData[0].meshName = "domain";
d_meshData[0].mesh = std::make_shared<IO::DomainMesh>( 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 PhaseVar = std::make_shared<IO::Variable>();
auto PressVar = std::make_shared<IO::Variable>(); auto PressVar = std::make_shared<IO::Variable>();
auto VxVar = std::make_shared<IO::Variable>(); auto VxVar = std::make_shared<IO::Variable>();
@ -878,7 +802,6 @@ runAnalysis::runAnalysis( ScaLBL_ColorModel &ColorModel)
d_meshData[0].vars.push_back(BlobIDVar); d_meshData[0].vars.push_back(BlobIDVar);
} }
// Initialize the comms // Initialize the comms
for (int i = 0; i < 1024; i++) for (int i = 0; i < 1024; i++)
d_comm_used[i] = false; d_comm_used[i] = false;
@ -887,13 +810,11 @@ runAnalysis::runAnalysis( ScaLBL_ColorModel &ColorModel)
auto method = db->getWithDefault<std::string>("load_balance", "default"); auto method = db->getWithDefault<std::string>("load_balance", "default");
createThreads(method, N_threads); createThreads(method, N_threads);
} }
runAnalysis::~runAnalysis() runAnalysis::~runAnalysis() {
{
// Finish processing analysis // Finish processing analysis
finish(); finish();
} }
void runAnalysis::finish() void runAnalysis::finish() {
{
PROFILE_START("finish"); PROFILE_START("finish");
// Wait for the work items to finish // Wait for the work items to finish
d_tpool.wait_pool_finished(); d_tpool.wait_pool_finished();
@ -908,12 +829,10 @@ void runAnalysis::finish()
PROFILE_STOP("finish"); PROFILE_STOP("finish");
} }
/****************************************************************** /******************************************************************
* Set the thread affinities * * Set the thread affinities *
******************************************************************/ ******************************************************************/
void print( const std::vector<int> &ids ) void print(const std::vector<int> &ids) {
{
if (ids.empty()) if (ids.empty())
return; return;
printf("%i", ids[0]); printf("%i", ids[0]);
@ -921,16 +840,16 @@ void print( const std::vector<int> &ids )
printf(", %i", ids[i]); printf(", %i", ids[i]);
printf("\n"); 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 // Check if we are not using analysis threads
if (method == "none") if (method == "none")
return; return;
// Check if we have thread support // Check if we have thread support
auto thread_support = Utilities::MPI::queryThreadSupport(); auto thread_support = Utilities::MPI::queryThreadSupport();
if ( thread_support != Utilities::MPI::ThreadSupport::MULTIPLE && N_threads > 0 ) if (thread_support != Utilities::MPI::ThreadSupport::MULTIPLE &&
std::cerr N_threads > 0)
<< "Warning: Failed to start MPI with necessary thread support, errors may occur\n"; std::cerr << "Warning: Failed to start MPI with necessary thread "
"support, errors may occur\n";
// Create the threads // Create the threads
const auto cores = d_tpool.getProcessAffinity(); const auto cores = d_tpool.getProcessAffinity();
if (N_threads == 0) { if (N_threads == 0) {
@ -961,12 +880,10 @@ void runAnalysis::createThreads( const std::string &method, int N_threads )
} }
} }
/****************************************************************** /******************************************************************
* Check which analysis we want to perform * * Check which analysis we want to perform *
******************************************************************/ ******************************************************************/
AnalysisType runAnalysis::computeAnalysisType( int timestep ) AnalysisType runAnalysis::computeAnalysisType(int timestep) {
{
AnalysisType type = AnalysisType::AnalyzeNone; AnalysisType type = AnalysisType::AnalyzeNone;
if (timestep % d_analysis_interval + 8 == d_analysis_interval) { if (timestep % d_analysis_interval + 8 == d_analysis_interval) {
// Copy the phase indicator field for the earlier timestep // Copy the phase indicator field for the earlier timestep
@ -1009,13 +926,12 @@ AnalysisType runAnalysis::computeAnalysisType( int timestep )
return type; return type;
} }
/****************************************************************** /******************************************************************
* Run the analysis * * Run the analysis *
******************************************************************/ ******************************************************************/
void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhase &Averages, void runAnalysis::run(int timestep, std::shared_ptr<Database> input_db,
const double *Phi, double *Pressure, double *Velocity, double *fq, double *Den ) TwoPhase &Averages, const double *Phi, double *Pressure,
{ double *Velocity, double *fq, double *Den) {
int N = d_N[0] * d_N[1] * d_N[2]; int N = d_N[0] * d_N[1] * d_N[2];
NULL_USE(N); NULL_USE(N);
NULL_USE(Phi); NULL_USE(Phi);
@ -1076,14 +992,16 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
if (d_regular) if (d_regular)
d_ScaLBL_Comm->RegularLayout(d_Map, Phi, Averages.Phase_tplus); d_ScaLBL_Comm->RegularLayout(d_Map, Phi, Averages.Phase_tplus);
else 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)); // memcpy(Averages.Phase_tplus.data(),phase->data(),N*sizeof(double));
} }
if (timestep % d_analysis_interval == 0) { if (timestep % d_analysis_interval == 0) {
if (d_regular) if (d_regular)
d_ScaLBL_Comm->RegularLayout(d_Map, Phi, Averages.Phase_tminus); d_ScaLBL_Comm->RegularLayout(d_Map, Phi, Averages.Phase_tminus);
else 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)); // memcpy(Averages.Phase_tminus.data(),phase->data(),N*sizeof(double));
} }
// if ( matches(type,AnalysisType::CopySimState) ) { // if ( matches(type,AnalysisType::CopySimState) ) {
@ -1106,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, Pressure, Averages.Press);
d_ScaLBL_Comm->RegularLayout(d_Map, &Velocity[0], Averages.Vel_x); 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[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-State", 1);
} }
std::shared_ptr<double> cfq, cDen; std::shared_ptr<double> cfq, cDen;
@ -1128,13 +1047,17 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
else else
ScaLBL_CopyToHost(phase->data(), Phi, N * sizeof(double)); ScaLBL_CopyToHost(phase->data(), Phi, N * sizeof(double));
auto new_index = std::make_shared<std::pair<int, IntArray>>( 0, IntArray() ); auto new_index =
auto new_ids = std::make_shared<std::pair<int, IntArray>>( 0, IntArray() ); 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 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, auto work1 = new BlobIdentificationWorkItem1(
phase, Averages.SDs, d_last_ids, new_index, new_ids, new_list, getComm() ); timestep, d_N[0], d_N[1], d_N[2], d_rank_info, phase, Averages.SDs,
auto work2 = new BlobIdentificationWorkItem2( timestep, d_N[0], d_N[1], d_N[2], d_rank_info, d_last_ids, new_index, new_ids, new_list, getComm());
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); work1->add_dependency(d_wait_blobID);
work2->add_dependency(d_tpool.add_work(work1)); work2->add_dependency(d_tpool.add_work(work1));
d_wait_blobID = d_tpool.add_work(work2); d_wait_blobID = d_tpool.add_work(work2);
@ -1147,11 +1070,12 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
// if (timestep%d_restart_interval==0){ // if (timestep%d_restart_interval==0){
// if ( matches(type,AnalysisType::ComputeAverages) ) { // if ( matches(type,AnalysisType::ComputeAverages) ) {
if (timestep % d_analysis_interval == 0) { if (timestep % d_analysis_interval == 0) {
auto work = auto work = new AnalysisWorkItem(type, timestep, Averages, d_last_index,
new AnalysisWorkItem( type, timestep, Averages, d_last_index, d_last_id_map, d_beta ); d_last_id_map, d_beta);
work->add_dependency(d_wait_blobID); work->add_dependency(d_wait_blobID);
work->add_dependency(d_wait_analysis); 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); d_wait_analysis = d_tpool.add_work(work);
} }
@ -1166,7 +1090,8 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
OutStream.close(); OutStream.close();
} }
// Write the restart file (using a seperate thread) // 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); work->add_dependency(d_wait_restart);
d_wait_restart = d_tpool.add_work(work); d_wait_restart = d_tpool.add_work(work);
} }
@ -1175,8 +1100,8 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
// if ( matches(type,AnalysisType::CreateRestart) ) { // if ( matches(type,AnalysisType::CreateRestart) ) {
if (timestep % d_restart_interval == 0) { if (timestep % d_restart_interval == 0) {
// Write the vis files // Write the vis files
auto work = auto work = new WriteVisWorkItem(timestep, d_meshData, Averages, d_n,
new WriteVisWorkItem( timestep, d_meshData, Averages, d_n, d_rank_info, getComm() ); d_rank_info, getComm());
work->add_dependency(d_wait_blobID); work->add_dependency(d_wait_blobID);
work->add_dependency(d_wait_analysis); work->add_dependency(d_wait_analysis);
work->add_dependency(d_wait_vis); work->add_dependency(d_wait_vis);
@ -1185,13 +1110,12 @@ void runAnalysis::run( int timestep, std::shared_ptr<Database> input_db, TwoPhas
PROFILE_STOP("run"); PROFILE_STOP("run");
} }
/****************************************************************** /******************************************************************
* Run the analysis * * Run the analysis *
******************************************************************/ ******************************************************************/
void runAnalysis::basic( int timestep, std::shared_ptr<Database> input_db, SubPhase &Averages, void runAnalysis::basic(int timestep, std::shared_ptr<Database> input_db,
const double *Phi, double *Pressure, double *Velocity, double *fq, double *Den ) SubPhase &Averages, const double *Phi, double *Pressure,
{ double *Velocity, double *fq, double *Den) {
int Nx = d_N[0]; int Nx = d_N[0];
int Ny = d_N[1]; int Ny = d_N[1];
int Nz = d_N[2]; int Nz = d_N[2];
@ -1240,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, &Den[d_Np], Averages.Rho_w);
d_ScaLBL_Comm->RegularLayout(d_Map, &Velocity[0], Averages.Vel_x); 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[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-State", 1);
} }
PROFILE_STOP("Copy data to host"); PROFILE_STOP("Copy data to host");
@ -1283,15 +1208,16 @@ void runAnalysis::basic( int timestep, std::shared_ptr<Database> input_db, SubPh
OutStream.close(); OutStream.close();
} }
// Write the restart file (using a seperate thread) // 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); work1->add_dependency(d_wait_restart);
d_wait_restart = d_tpool.add_work(work1); d_wait_restart = d_tpool.add_work(work1);
} }
if (timestep % d_visualization_interval == 0) { if (timestep % d_visualization_interval == 0) {
// Write the vis files // Write the vis files
auto work = auto work = new IOWorkItem(timestep, input_db, d_meshData, Averages,
new IOWorkItem( timestep, input_db, d_meshData, Averages, d_n, d_rank_info, getComm() ); d_n, d_rank_info, getComm());
work->add_dependency(d_wait_analysis); work->add_dependency(d_wait_analysis);
work->add_dependency(d_wait_subphase); work->add_dependency(d_wait_subphase);
work->add_dependency(d_wait_vis); work->add_dependency(d_wait_vis);
@ -1302,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, void runAnalysis::WriteVisData(int timestep, std::shared_ptr<Database> input_db,
SubPhase &Averages, const double *Phi, double *Pressure, double *Velocity, double *fq, SubPhase &Averages, const double *Phi,
double *Den ) double *Pressure, double *Velocity, double *fq,
{ double *Den) {
auto color_db = input_db->getDatabase("Color"); auto color_db = input_db->getDatabase("Color");
auto vis_db = input_db->getDatabase("Visualization"); auto vis_db = input_db->getDatabase("Visualization");
// int timestep = color_db->getWithDefault<int>( "timestep", 0 ); // int timestep = color_db->getWithDefault<int>( "timestep", 0 );
@ -1326,8 +1252,8 @@ void runAnalysis::WriteVisData( int timestep, std::shared_ptr<Database> input_db
PROFILE_START("write vis", 1); PROFILE_START("write vis", 1);
// if (Averages.WriteVis == true){ // if (Averages.WriteVis == true){
auto work2 = auto work2 = new IOWorkItem(timestep, input_db, d_meshData, Averages, d_n,
new IOWorkItem( timestep, input_db, d_meshData, Averages, d_n, d_rank_info, getComm() ); d_rank_info, getComm());
work2->add_dependency(d_wait_vis); work2->add_dependency(d_wait_vis);
d_wait_vis = d_tpool.add_work(work2); d_wait_vis = d_tpool.add_work(work2);

View File

@ -26,7 +26,6 @@
#include "models/ColorModel.h" #include "models/ColorModel.h"
#include <limits.h> #include <limits.h>
// Types of analysis // Types of analysis
enum class AnalysisType : uint64_t { enum class AnalysisType : uint64_t {
AnalyzeNone = 0, AnalyzeNone = 0,
@ -39,15 +38,13 @@ enum class AnalysisType : uint64_t {
ComputeSubphase = 0x40 ComputeSubphase = 0x40
}; };
//! Class to run the analysis in multiple threads //! Class to run the analysis in multiple threads
class runAnalysis class runAnalysis {
{
public: public:
//! Constructor //! Constructor
runAnalysis(std::shared_ptr<Database> db, const RankInfoStruct &rank_info, runAnalysis(std::shared_ptr<Database> db, const RankInfoStruct &rank_info,
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm, std::shared_ptr<Domain> dm, int Np, std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm,
bool Regular, IntArray Map ); std::shared_ptr<Domain> dm, int Np, bool Regular, IntArray Map);
runAnalysis(ScaLBL_ColorModel &ColorModel); runAnalysis(ScaLBL_ColorModel &ColorModel);
@ -55,13 +52,16 @@ public:
~runAnalysis(); ~runAnalysis();
//! Run the next analysis //! Run the next analysis
void run( int timestep, std::shared_ptr<Database> db, TwoPhase &Averages, const double *Phi, void run(int timestep, std::shared_ptr<Database> db, TwoPhase &Averages,
double *Pressure, double *Velocity, double *fq, double *Den ); 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, void basic(int timestep, std::shared_ptr<Database> db, SubPhase &Averages,
double *Pressure, double *Velocity, double *fq, double *Den ); const double *Phi, double *Pressure, double *Velocity,
void WriteVisData( int timestep, std::shared_ptr<Database> vis_db, SubPhase &Averages, double *fq, double *Den);
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 //! Finish all active analysis
void finish(); void finish();
@ -80,8 +80,8 @@ public:
* that all threads run on independent cores * that all threads run on independent cores
* @param[in] N_threads Number of threads, only used by some of the methods * @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: private:
runAnalysis(); runAnalysis();
@ -90,8 +90,7 @@ private:
AnalysisType computeAnalysisType(int timestep); AnalysisType computeAnalysisType(int timestep);
public: public:
class commWrapper class commWrapper {
{
public: public:
Utilities::MPI comm; Utilities::MPI comm;
int tag; int tag;
@ -112,7 +111,8 @@ private:
std::array<int, 3> d_N; // Number of local cells with ghosts std::array<int, 3> d_N; // Number of local cells with ghosts
int d_Np; int d_Np;
int d_rank; 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; int d_subphase_analysis_interval;
double d_beta; double d_beta;
bool d_regular; bool d_regular;

View File

@ -20,19 +20,15 @@
#include "analysis/filters.h" #include "analysis/filters.h"
#include "analysis/imfilter.h" #include "analysis/imfilter.h"
template <class T> inline int sign(T x) {
template<class T>
inline int sign( T x )
{
if (x == 0) if (x == 0)
return 0; return 0;
return x > 0 ? 1 : -1; return x > 0 ? 1 : -1;
} }
inline float trilinear(float dx, float dy, float dz, float f1, float f2, 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; double f, dx2, dy2, dz2, h0, h1;
dx2 = 1.0 - dx; dx2 = 1.0 - dx;
dy2 = 1.0 - dy; dy2 = 1.0 - dy;
@ -43,9 +39,7 @@ inline float trilinear( float dx, float dy, float dz, float f1, float f2,
return (f); return (f);
} }
void InterpolateMesh(const Array<float> &Coarse, Array<float> &Fine) {
void InterpolateMesh( const Array<float> &Coarse, Array<float> &Fine )
{
PROFILE_START("InterpolateMesh"); PROFILE_START("InterpolateMesh");
// Interpolate values from a Coarse mesh to a fine one // Interpolate values from a Coarse mesh to a fine one
@ -95,9 +89,10 @@ void InterpolateMesh( const Array<float> &Coarse, Array<float> &Fine )
int i2 = i0 + 2; int i2 = i0 + 2;
float dx = ((i + 0.5) - (i0 + 0.5) * hx) / hx; float dx = ((i + 0.5) - (i0 + 0.5) * hx) / hx;
ASSERT(i0 >= -1 && i0 < nx + 1 && dx >= 0 && dx <= 1); ASSERT(i0 >= -1 && i0 < nx + 1 && dx >= 0 && dx <= 1);
float val = trilinear( dx, dy, dz, float val = trilinear(
Coarse(i1,j1,k1), Coarse(i2,j1,k1), Coarse(i1,j2,k1), Coarse(i2,j2,k1), dx, dy, dz, Coarse(i1, j1, k1), Coarse(i2, j1, k1),
Coarse(i1,j1,k2), Coarse(i2,j1,k2), Coarse(i1,j2,k2), Coarse(i2,j2,k2) ); 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; Fine(i + 1, j + 1, k + 1) = mapvalue * val;
} }
} }
@ -105,10 +100,9 @@ void InterpolateMesh( const Array<float> &Coarse, Array<float> &Fine )
PROFILE_STOP("InterpolateMesh"); PROFILE_STOP("InterpolateMesh");
} }
// Smooth the data using the distance // 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++) { for (size_t i = 0; i < VOL.length(); i++) {
// use exponential weight based on the distance // use exponential weight based on the distance
float dst = Dist(i); float dst = Dist(i);
@ -119,10 +113,8 @@ void smooth( const Array<float>& VOL, const Array<float>& Dist, float sigma, Arr
fillFloat.fill(MultiScaleSmooth); fillFloat.fill(MultiScaleSmooth);
} }
// Segment the data // 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()); ASSERT(data.size() == ID.size());
for (size_t i = 0; i < data.length(); i++) { for (size_t i = 0; i < data.length(); i++) {
if (data(i) > tol) if (data(i) > tol)
@ -132,10 +124,8 @@ void segment( const Array<float>& data, Array<char>& ID, float tol )
} }
} }
// Remove disconnected phases // 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 // Run blob identification to remove disconnected volumes
BlobIDArray GlobalBlobID; BlobIDArray GlobalBlobID;
DoubleArray SignDist(ID.size()); DoubleArray SignDist(ID.size());
@ -145,7 +135,8 @@ void removeDisconnected( Array<char>& ID, const Domain& Dm )
Phase(i) = 1; Phase(i) = 1;
} }
ComputeGlobalBlobIDs(ID.size(0) - 2, ID.size(1) - 2, ID.size(2) - 2, 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++) { for (size_t i = 0; i < ID.length(); i++) {
if (GlobalBlobID(i) > 0) if (GlobalBlobID(i) > 0)
ID(i) = 0; ID(i) = 0;
@ -153,13 +144,12 @@ void removeDisconnected( Array<char>& ID, const Domain& Dm )
} }
} }
// Solve a level (without any coarse level information) // Solve a level (without any coarse level information)
void solve(const Array<float> &VOL, Array<float> &Mean, Array<char> &ID, void solve(const Array<float> &VOL, Array<float> &Mean, Array<char> &ID,
Array<float>& Dist, Array<float>& MultiScaleSmooth, Array<float>& NonLocalMean, Array<float> &Dist, Array<float> &MultiScaleSmooth,
fillHalo<float>& fillFloat, const Domain& Dm, int nprocx, Array<float> &NonLocalMean, fillHalo<float> &fillFloat,
float threshold, float lamda, float sigsq, int depth) const Domain &Dm, int nprocx, float threshold, float lamda,
{ float sigsq, int depth) {
PROFILE_SCOPED(timer, "solve"); PROFILE_SCOPED(timer, "solve");
// Compute the median filter on the sparse array // Compute the median filter on the sparse array
Med3D(VOL, Mean); Med3D(VOL, Mean);
@ -172,19 +162,18 @@ void solve( const Array<float>& VOL, Array<float>& Mean, Array<char>& ID,
// Compute non-local mean // Compute non-local mean
// int depth = 5; // int depth = 5;
// float sigsq=0.1; // 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); NULL_USE(nlm_count);
fillFloat.fill(NonLocalMean); fillFloat.fill(NonLocalMean);
} }
// Refine a solution from a coarse grid to a fine grid // Refine a solution from a coarse grid to a fine grid
void refine( const Array<float>& Dist_coarse, void refine(const Array<float> &Dist_coarse, const Array<float> &VOL,
const Array<float>& VOL, Array<float>& Mean, Array<char>& ID, Array<float> &Mean, Array<char> &ID, Array<float> &Dist,
Array<float>& Dist, Array<float>& MultiScaleSmooth, Array<float>& NonLocalMean, Array<float> &MultiScaleSmooth, Array<float> &NonLocalMean,
fillHalo<float> &fillFloat, const Domain &Dm, int nprocx, int level, 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"); PROFILE_SCOPED(timer, "refine");
int ratio[3] = {int(Dist.size(0) / Dist_coarse.size(0)), int ratio[3] = {int(Dist.size(0) / Dist_coarse.size(0)),
int(Dist.size(1) / Dist_coarse.size(1)), int(Dist.size(1) / Dist_coarse.size(1)),
@ -202,22 +191,26 @@ void refine( const Array<float>& Dist_coarse,
Dist(i) = 0; Dist(i) = 0;
} }
fillFloat.fill(Dist); 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; bool zero = data[0] == 0 || data[2] == 0;
return zero ? data[1] * 1e-12 : data[1]; return zero ? data[1] * 1e-12 : data[1];
}; };
std::vector<imfilter::BC> BC(3, imfilter::BC::replicate); 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); Dist = imfilter::imfilter_separable<float>(Dist, {1, 1, 1}, filter_set, BC);
fillFloat.fill(Dist); fillFloat.fill(Dist);
// Smooth the volume data // 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); smooth(VOL, Dist, h, MultiScaleSmooth, fillFloat);
// Compute non-local mean // Compute non-local mean
// int depth = 3; // int depth = 3;
// float sigsq = 0.1; // 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); NULL_USE(nlm_count);
fillFloat.fill(NonLocalMean); fillFloat.fill(NonLocalMean);
segment(NonLocalMean, ID, 0.001); segment(NonLocalMean, ID, 0.001);
@ -235,14 +228,13 @@ void refine( const Array<float>& Dist_coarse,
} }
} }
// Remove regions that are likely noise by shrinking the volumes by dx, // 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 // removing all values that are more than dx+delta from the surface, and then
// growing by dx+delta and intersecting with the original data // growing by dx+delta and intersecting with the original data
void filter_final(Array<char> &ID, Array<float> &Dist, void filter_final(Array<char> &ID, Array<float> &Dist,
fillHalo<float> &fillFloat, const Domain &Dm, 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"); PROFILE_SCOPED(timer, "filter_final");
int rank = Dm.Comm.getRank(); int rank = Dm.Comm.getRank();
int Nx = Dm.Nx - 2; int Nx = Dm.Nx - 2;
@ -257,7 +249,8 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
float tmp = 0; float tmp = 0;
for (size_t i = 0; i < Dist0.length(); i++) for (size_t i = 0; i < Dist0.length(); i++)
tmp += Dist0(i) * Dist0(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 dx1 = 0.3 * tmp;
const float dx2 = 1.05 * dx1; const float dx2 = 1.05 * dx1;
if (rank == 0) if (rank == 0)
@ -289,8 +282,10 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
} }
} }
// Find regions of uncertainty that are entirely contained within another region // 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<double> fillDouble(Dm.Comm, Dm.rank_info, {Nx, Ny, Nz}, {1, 1, 1},
fillHalo<BlobIDType> fillInt(Dm.Comm,Dm.rank_info,{Nx,Ny,Nz},{1,1,1},0,1); 0, 1);
fillHalo<BlobIDType> fillInt(Dm.Comm, Dm.rank_info, {Nx, Ny, Nz}, {1, 1, 1},
0, 1);
BlobIDArray GlobalBlobID; BlobIDArray GlobalBlobID;
DoubleArray SignDist(ID.size()); DoubleArray SignDist(ID.size());
for (size_t i = 0; i < ID.length(); i++) for (size_t i = 0; i < ID.length(); i++)
@ -298,7 +293,8 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
fillDouble.fill(SignDist); fillDouble.fill(SignDist);
DoubleArray Phase(ID.size()); DoubleArray Phase(ID.size());
Phase.fill(1); 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); fillInt.fill(GlobalBlobID);
int N_blobs = Dm.Comm.maxReduce(GlobalBlobID.max() + 1); int N_blobs = Dm.Comm.maxReduce(GlobalBlobID.max() + 1);
std::vector<float> mean(N_blobs, 0); std::vector<float> mean(N_blobs, 0);
@ -364,20 +360,20 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
fillFloat.fill(Dist); fillFloat.fill(Dist);
} }
// Filter the original data // 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"); PROFILE_START("Filter source data");
int Nx = Dm.Nx - 2; int Nx = Dm.Nx - 2;
int Ny = Dm.Ny - 2; int Ny = Dm.Ny - 2;
int Nz = Dm.Nz - 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 // Perform a hot-spot filter on the data
std::vector<imfilter::BC> BC = { imfilter::BC::replicate, imfilter::BC::replicate, imfilter::BC::replicate }; std::vector<imfilter::BC> BC = {imfilter::BC::replicate,
std::function<float(const Array<float>&)> filter_3D = []( const Array<float>& data ) 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 min1 = std::min(data(0, 1, 1), data(2, 1, 1));
float min2 = std::min(data(1, 0, 1), data(1, 2, 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)); float min3 = std::min(data(1, 1, 0), data(1, 1, 2));
@ -388,14 +384,15 @@ void filter_src( const Domain& Dm, Array<float>& src )
float max = std::max(max1, std::max(max2, max3)); float max = std::max(max1, std::max(max2, max3));
return std::max(std::min(data(1, 1, 1), max), min); 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 min = std::min(data(0), data(2));
float max = std::max(data(0), data(2)); float max = std::max(data(0), data(2));
return std::max(std::min(data(1), max), min); return std::max(std::min(data(1), max), min);
}; };
//LOCVOL[0] = imfilter::imfilter<float>( LOCVOL[0], {1,1,1}, filter_3D, BC ); //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); src = imfilter::imfilter_separable<float>(src, {1, 1, 1}, filter_set, BC);
fillFloat.fill(src); fillFloat.fill(src);
// Perform a gaussian filter on the data // Perform a gaussian filter on the data

View File

@ -21,8 +21,6 @@
#include "common/Domain.h" #include "common/Domain.h"
#include "common/Communication.h" #include "common/Communication.h"
/*! /*!
* @brief Interpolate between meshes * @brief Interpolate between meshes
* @details This routine interpolates from a coarse to a fine mesh * @details This routine interpolates from a coarse to a fine mesh
@ -31,34 +29,30 @@
*/ */
void InterpolateMesh(const Array<float> &Coarse, Array<float> &Fine); void InterpolateMesh(const Array<float> &Coarse, Array<float> &Fine);
// Smooth the data using the distance // 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 // 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);
// Remove disconnected phases // Remove disconnected phases
void removeDisconnected(Array<char> &ID, const Domain &Dm); void removeDisconnected(Array<char> &ID, const Domain &Dm);
// Solve a level (without any coarse level information) // Solve a level (without any coarse level information)
void solve(const Array<float> &VOL, Array<float> &Mean, Array<char> &ID, void solve(const Array<float> &VOL, Array<float> &Mean, Array<char> &ID,
Array<float>& Dist, Array<float>& MultiScaleSmooth, Array<float>& NonLocalMean, Array<float> &Dist, Array<float> &MultiScaleSmooth,
fillHalo<float>& fillFloat, const Domain& Dm, int nprocx, Array<float> &NonLocalMean, fillHalo<float> &fillFloat,
float threshold, float lamda, float sigsq, int depth); const Domain &Dm, int nprocx, float threshold, float lamda,
float sigsq, int depth);
// Refine a solution from a coarse grid to a fine grid // Refine a solution from a coarse grid to a fine grid
void refine( const Array<float>& Dist_coarse, void refine(const Array<float> &Dist_coarse, const Array<float> &VOL,
const Array<float>& VOL, Array<float>& Mean, Array<char>& ID, Array<float> &Mean, Array<char> &ID, Array<float> &Dist,
Array<float>& Dist, Array<float>& MultiScaleSmooth, Array<float>& NonLocalMean, Array<float> &MultiScaleSmooth, Array<float> &NonLocalMean,
fillHalo<float> &fillFloat, const Domain &Dm, int nprocx, int level, 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);
// Remove regions that are likely noise by shrinking the volumes by dx, // 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 // removing all values that are more than dx+delta from the surface, and then
// growing by dx+delta and intersecting with the original data // growing by dx+delta and intersecting with the original data
@ -66,9 +60,7 @@ void filter_final( Array<char>& ID, Array<float>& Dist,
fillHalo<float> &fillFloat, const Domain &Dm, fillHalo<float> &fillFloat, const Domain &Dm,
Array<float> &Mean, Array<float> &Dist1, Array<float> &Dist2); Array<float> &Mean, Array<float> &Dist1, Array<float> &Dist2);
// Filter the original data // Filter the original data
void filter_src(const Domain &Dm, Array<float> &src); void filter_src(const Domain &Dm, Array<float> &src);
#endif #endif

View File

@ -27,13 +27,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
/*! /*!
* Class Array is a multi-dimensional array class written by Mark Berrill * Class Array is a multi-dimensional array class written by Mark Berrill
*/ */
template<class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator> class Array final {
class Array final
{
public: // Constructors / assignment operators public: // Constructors / assignment operators
/*! /*!
* Create a new empty Array * Create a new empty Array
@ -111,7 +108,6 @@ public: // Constructors / assignment operators
*/ */
Array(std::initializer_list<std::initializer_list<TYPE>> data); Array(std::initializer_list<std::initializer_list<TYPE>> data);
/*! /*!
* Copy constructor * Copy constructor
* @param rhs Array to copy * @param rhs Array to copy
@ -154,24 +150,22 @@ public: // Constructors / assignment operators
//! Set is copyable //! Set is copyable
inline void setFixedSize(bool flag) { d_isFixedSize = flag; } inline void setFixedSize(bool flag) { d_isFixedSize = flag; }
public: // Views/copies/subset public: // Views/copies/subset
/*! /*!
* Create a multi-dimensional Array view to a raw block of data * Create a multi-dimensional Array view to a raw block of data
* @param N Number of elements in each dimension * @param N Number of elements in each dimension
* @param data Pointer to the data * @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 * Create a multi-dimensional Array view to a raw block of data
* @param N Number of elements in each dimension * @param N Number of elements in each dimension
* @param data Pointer to the data * @param data Pointer to the data
*/ */
static std::unique_ptr<const Array> constView( const ArraySize &N, static std::unique_ptr<const Array>
std::shared_ptr<const TYPE> const &data ); constView(const ArraySize &N, std::shared_ptr<const TYPE> const &data);
/*! /*!
* Make this object a view of the src * Make this object a view of the src
@ -199,9 +193,8 @@ public: // Views/copies/subset
* @param isCopyable Once the view is created, can the array be copied * @param isCopyable Once the view is created, can the array be copied
* @param isFixedSize Once the view is created, is the array size fixed * @param isFixedSize Once the view is created, is the array size fixed
*/ */
inline void viewRaw( inline void viewRaw(int ndim, const size_t *dims, TYPE *data,
int ndim, const size_t *dims, TYPE *data, bool isCopyable = true, bool isFixedSize = true ) bool isCopyable = true, bool isFixedSize = true) {
{
viewRaw(ArraySize(ndim, dims), data, isCopyable, isFixedSize); viewRaw(ArraySize(ndim, dims), data, isCopyable, isFixedSize);
} }
@ -217,7 +210,8 @@ public: // Views/copies/subset
* @param isCopyable Once the view is created, can the array be copied * @param isCopyable Once the view is created, can the array be copied
* @param isFixedSize Once the view is created, is the array size fixed * @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). * Create an array view of the given data (expert use only).
@ -229,8 +223,7 @@ public: // Views/copies/subset
* @param N Number of elements in each dimension * @param N Number of elements in each dimension
* @param data Pointer to the data * @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; Array x;
x.viewRaw(N, data, true, true); x.viewRaw(N, data, true, true);
return x; return x;
@ -242,35 +235,30 @@ public: // Views/copies/subset
*/ */
template <class TYPE2> template <class TYPE2>
static inline std::unique_ptr<Array<TYPE2, FUN, Allocator>> 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()); auto array2 = std::make_unique<Array<TYPE2>>(array->size());
array2.copy(*array); array2.copy(*array);
return array2; return array2;
} }
/*! /*!
* Convert an array of one type to another. This may or may not allocate new memory. * Convert an array of one type to another. This may or may not allocate new memory.
* @param array Input array * @param array Input array
*/ */
template <class TYPE2> template <class TYPE2>
static inline std::unique_ptr<const Array<TYPE2, FUN, Allocator>> 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()); auto array2 = std::make_unique<Array<TYPE2>>(array->size());
array2.copy(*array); array2.copy(*array);
return array2; return array2;
} }
/*! /*!
* Copy and convert data from another array to this array * Copy and convert data from another array to this array
* @param array Source array * @param array Source array
*/ */
template <class TYPE2, class FUN2, class Allocator2> 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()); resize(array.size());
copy(array.data()); copy(array.data());
} }
@ -280,38 +268,32 @@ public: // Views/copies/subset
* Note: The current array must be allocated to the proper size first. * Note: The current array must be allocated to the proper size first.
* @param data Source data * @param data Source data
*/ */
template<class TYPE2> template <class TYPE2> inline void copy(const TYPE2 *data);
inline void copy( const TYPE2 *data );
/*! /*!
* Copy and convert data from this array to a raw vector. * Copy and convert data from this array to a raw vector.
* @param data Source data * @param data Source data
*/ */
template<class TYPE2> template <class TYPE2> inline void copyTo(TYPE2 *data) const;
inline void copyTo( TYPE2 *data ) const;
/*! /*!
* Copy and convert data from this array to a new array * Copy and convert data from this array to a new array
*/ */
template <class TYPE2> 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()); Array<TYPE2, FUN, std::allocator<TYPE2>> dst(this->size());
copyTo(dst.data()); copyTo(dst.data());
return dst; return dst;
} }
/*! swap the raw data pointers for the Arrays after checking for compatibility */ /*! swap the raw data pointers for the Arrays after checking for compatibility */
void swap(Array &other); void swap(Array &other);
/*! /*!
* Fill the array with the given value * Fill the array with the given value
* @param y Value to fill * @param y Value to fill
*/ */
inline void fill( const TYPE &y ) inline void fill(const TYPE &y) {
{
for (auto &x : *this) for (auto &x : *this)
x = y; x = y;
} }
@ -320,14 +302,11 @@ public: // Views/copies/subset
* Scale the array by the given value * Scale the array by the given value
* @param y Value to scale by * @param y Value to scale by
*/ */
template<class TYPE2> template <class TYPE2> inline void scale(const TYPE2 &y) {
inline void scale( const TYPE2 &y )
{
for (auto &x : *this) for (auto &x : *this)
x *= y; x *= y;
} }
/*! /*!
* Set the values of this array to pow(base, exp) * Set the values of this array to pow(base, exp)
* @param base Base array * @param base Base array
@ -335,52 +314,44 @@ public: // Views/copies/subset
*/ */
void pow(const Array &base, const TYPE &exp); void pow(const Array &base, const TYPE &exp);
//! Destructor //! Destructor
~Array(); ~Array();
//! Clear the data in the array //! Clear the data in the array
void clear(); void clear();
//! Return the size of the Array //! Return the size of the Array
inline int ndim() const { return d_size.ndim(); } inline int ndim() const { return d_size.ndim(); }
//! Return the size of the Array //! Return the size of the Array
inline const ArraySize &size() const { return d_size; } inline const ArraySize &size() const { return d_size; }
//! Return the size of the Array //! Return the size of the Array
inline size_t size(int d) const { return d_size[d]; } inline size_t size(int d) const { return d_size[d]; }
//! Return the size of the Array //! Return the size of the Array
inline size_t length() const { return d_size.length(); } inline size_t length() const { return d_size.length(); }
//! Return true if the Array is empty //! Return true if the Array is empty
inline bool empty() const { return d_size.length() == 0; } inline bool empty() const { return d_size.length() == 0; }
//! Return true if the Array is not empty //! Return true if the Array is not empty
inline operator bool() const { return d_size.length() != 0; } inline operator bool() const { return d_size.length() != 0; }
/*! /*!
* Resize the Array * Resize the Array
* @param N NUmber of elements * @param N NUmber of elements
*/ */
inline void resize(size_t N) { resize(ArraySize(N)); } inline void resize(size_t N) { resize(ArraySize(N)); }
/*! /*!
* Resize the Array * Resize the Array
* @param N_row Number of rows * @param N_row Number of rows
* @param N_col Number of columns * @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 * Resize the Array
@ -388,7 +359,9 @@ public: // Views/copies/subset
* @param N2 Number of columns * @param N2 Number of columns
* @param N3 Number of elements in the third dimension * @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 * Resize the Array
@ -396,7 +369,6 @@ public: // Views/copies/subset
*/ */
void resize(const ArraySize &N); void resize(const ArraySize &N);
/*! /*!
* Resize the given dimension of the array * Resize the given dimension of the array
* @param dim The dimension to resize * @param dim The dimension to resize
@ -405,20 +377,17 @@ public: // Views/copies/subset
*/ */
void resizeDim(int dim, size_t N, const TYPE &value); void resizeDim(int dim, size_t N, const TYPE &value);
/*! /*!
* Reshape the Array (total size of array will not change) * Reshape the Array (total size of array will not change)
* @param N Number of elements in each dimension * @param N Number of elements in each dimension
*/ */
void reshape(const ArraySize &N); void reshape(const ArraySize &N);
/*! /*!
* Remove singleton dimensions. * Remove singleton dimensions.
*/ */
void squeeze(); void squeeze();
/*! /*!
* Reshape the Array so that the number of dimensions is the * Reshape the Array so that the number of dimensions is the
* max of ndim and the largest dim>1. * max of ndim and the largest dim>1.
@ -426,21 +395,18 @@ public: // Views/copies/subset
*/ */
inline void setNdim(int ndim) { d_size.setNdim(ndim); } inline void setNdim(int ndim) { d_size.setNdim(ndim); }
/*! /*!
* Subset the Array * Subset the Array
* @param index Index to subset (imin,imax,jmin,jmax,kmin,kmax,...) * @param index Index to subset (imin,imax,jmin,jmax,kmin,kmax,...)
*/ */
Array subset(const std::vector<size_t> &index) const; Array subset(const std::vector<size_t> &index) const;
/*! /*!
* Subset the Array * Subset the Array
* @param index Index to subset (ix:kx:jx,iy:ky:jy,...) * @param index Index to subset (ix:kx:jx,iy:ky:jy,...)
*/ */
Array subset(const std::vector<Range<size_t>> &index) const; Array subset(const std::vector<Range<size_t>> &index) const;
/*! /*!
* Copy data from an array into a subset of this array * Copy data from an array into a subset of this array
* @param index Index of the subset (imin,imax,jmin,jmax,kmin,kmax,...) * @param index Index of the subset (imin,imax,jmin,jmax,kmin,kmax,...)
@ -453,7 +419,8 @@ public: // Views/copies/subset
* @param index Index of the subset * @param index Index of the subset
* @param subset The subset array to copy from * @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 * Add data from an array into a subset of this array
@ -467,22 +434,23 @@ public: // Views/copies/subset
* @param index Index of the subset * @param index Index of the subset
* @param subset The subset array to add from * @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 public: // Accessors
/*! /*!
* Access the desired element * Access the desired element
* @param i The row index * @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 * Access the desired element
* @param i The row index * @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)]; return d_data[d_size.index(i)];
} }
@ -491,8 +459,7 @@ public: // Accessors
* @param i The row index * @param i The row index
* @param j The column 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)]; return d_data[d_size.index(i, j)];
} }
@ -501,8 +468,7 @@ public: // Accessors
* @param i The row index * @param i The row index
* @param j The column 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)]; return d_data[d_size.index(i, j)];
} }
@ -512,8 +478,7 @@ public: // Accessors
* @param j The column index * @param j The column index
* @param k The third 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)]; return d_data[d_size.index(i, j, k)];
} }
@ -523,8 +488,8 @@ public: // Accessors
* @param j The column index * @param j The column index
* @param k The third 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)]; return d_data[d_size.index(i, j, k)];
} }
@ -535,8 +500,8 @@ public: // Accessors
* @param i3 The third index * @param i3 The third index
* @param i4 The fourth 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)]; return d_data[d_size.index(i1, i2, i3, i4)];
} }
@ -547,9 +512,8 @@ public: // Accessors
* @param i3 The third index * @param i3 The third index
* @param i4 The fourth index * @param i4 The fourth index
*/ */
ARRAY_ATTRIBUTE inline const TYPE & ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i1, size_t i2,
operator()( size_t i1, size_t i2, size_t i3, size_t i4 ) const size_t i3, size_t i4) const {
{
return d_data[d_size.index(i1, i2, i3, i4)]; return d_data[d_size.index(i1, i2, i3, i4)];
} }
@ -561,8 +525,8 @@ public: // Accessors
* @param i4 The fourth index * @param i4 The fourth index
* @param i5 The fifth 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)]; return d_data[d_size.index(i1, i2, i3, i4, i5)];
} }
@ -575,8 +539,7 @@ public: // Accessors
* @param i5 The fifth index * @param i5 The fifth index
*/ */
ARRAY_ATTRIBUTE inline const TYPE & 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)]; return d_data[d_size.index(i1, i2, i3, i4, i5)];
} }
@ -584,8 +547,7 @@ public: // Accessors
* Access the desired element as a raw pointer * Access the desired element as a raw pointer
* @param i The global index * @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]; return i >= d_size.length() ? nullptr : &d_data[i];
} }
@ -593,8 +555,7 @@ public: // Accessors
* Access the desired element as a raw pointer * Access the desired element as a raw pointer
* @param i The global index * @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]; return i >= d_size.length() ? nullptr : &d_data[i];
} }
@ -622,14 +583,15 @@ public: // Accessors
//! Return the pointer to the raw data //! Return the pointer to the raw data
ARRAY_ATTRIBUTE inline const TYPE *data() const { return d_data; } ARRAY_ATTRIBUTE inline const TYPE *data() const { return d_data; }
public: // Operator overloading public: // Operator overloading
//! Check if two matrices are equal //! Check if two matrices are equal
// Equality means the dimensions and data have to be identical // Equality means the dimensions and data have to be identical
bool operator==(const Array &rhs) const; bool operator==(const Array &rhs) const;
//! Check if two matrices are not equal //! 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 //! Add another array
Array &operator+=(const Array &rhs); Array &operator+=(const Array &rhs);
@ -643,7 +605,6 @@ public: // Operator overloading
//! Subtract a scalar //! Subtract a scalar
Array &operator-=(const TYPE &rhs); Array &operator-=(const TYPE &rhs);
public: // Math operations public: // Math operations
//! Concatenates the arrays along the dimension dim. //! Concatenates the arrays along the dimension dim.
static Array cat(const std::vector<Array> &x, int dim = 0); static Array cat(const std::vector<Array> &x, int dim = 0);
@ -709,13 +670,13 @@ public: // Math operations
TYPE mean(const std::vector<Range<size_t>> &index) const; TYPE mean(const std::vector<Range<size_t>> &index) const;
//! Find all elements that match the operator //! 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; std::function<bool(const TYPE &, const TYPE &)> compare) const;
//! Print an array //! Print an array
void void print(std::ostream &os, const std::string &name = "A",
print( std::ostream &os, const std::string &name = "A", const std::string &prefix = "" ) const; const std::string &prefix = "") const;
//! Transpose an array //! Transpose an array
Array reverseDim() const; Array reverseDim() const;
@ -755,7 +716,8 @@ public: // Math operations
* @param[in] fun The function operation * @param[in] fun The function operation
* @param[in] x The input array * @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) * Perform a element-wise operation z = f(x,y)
@ -764,8 +726,7 @@ public: // Math operations
* @param[in] y The second array * @param[in] y The second array
*/ */
static Array transform(std::function<TYPE(const TYPE &, const TYPE &)> fun, static Array transform(std::function<TYPE(const TYPE &, const TYPE &)> fun,
const Array &x, const Array &x, const Array &y);
const Array &y );
/*! /*!
* axpby operation: this = alpha*x + beta*this * axpby operation: this = alpha*x + beta*this
@ -779,7 +740,9 @@ public: // Math operations
* Linear interpolation * Linear interpolation
* @param[in] x Position as a decimal index * @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 * Linear interpolation
@ -806,7 +769,8 @@ private:
private: private:
inline void checkSubsetIndex(const std::vector<Range<size_t>> &range) const; 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, static inline void getSubsetArrays(const std::vector<Range<size_t>> &range,
std::array<size_t, 5> &first, std::array<size_t, 5> &first,
std::array<size_t, 5> &last, std::array<size_t, 5> &last,
@ -814,12 +778,10 @@ private:
std::array<size_t, 5> &N); std::array<size_t, 5> &N);
}; };
/******************************************************** /********************************************************
* ostream operator * * 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]; out << "[" << s[0];
for (size_t i = 1; i < s.ndim(); i++) for (size_t i = 1; i < s.ndim(); i++)
out << "," << s[i]; out << "," << s[i];
@ -827,70 +789,64 @@ inline std::ostream &operator<<( std::ostream &out, const ArraySize &s )
return out; return out;
} }
/******************************************************** /********************************************************
* Math operations * * Math operations *
********************************************************/ ********************************************************/
template <class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator>
inline Array<TYPE, FUN, Allocator> operator+( inline Array<TYPE, FUN, Allocator>
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b ) operator+(const Array<TYPE, FUN, Allocator> &a,
{ const Array<TYPE, FUN, Allocator> &b) {
Array<TYPE, FUN, Allocator> c; Array<TYPE, FUN, Allocator> c;
const auto &op = [](const TYPE &a, const TYPE &b) { return a + b; }; const auto &op = [](const TYPE &a, const TYPE &b) { return a + b; };
FUN::transform(op, a, b, c); FUN::transform(op, a, b, c);
return c; return c;
} }
template <class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator>
inline Array<TYPE, FUN, Allocator> operator-( inline Array<TYPE, FUN, Allocator>
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b ) operator-(const Array<TYPE, FUN, Allocator> &a,
{ const Array<TYPE, FUN, Allocator> &b) {
Array<TYPE, FUN, Allocator> c; Array<TYPE, FUN, Allocator> c;
const auto &op = [](const TYPE &a, const TYPE &b) { return a - b; }; const auto &op = [](const TYPE &a, const TYPE &b) { return a - b; };
FUN::transform(op, a, b, c); FUN::transform(op, a, b, c);
return c; return c;
} }
template <class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator>
inline Array<TYPE, FUN, Allocator> operator*( inline Array<TYPE, FUN, Allocator>
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b ) operator*(const Array<TYPE, FUN, Allocator> &a,
{ const Array<TYPE, FUN, Allocator> &b) {
Array<TYPE, FUN, Allocator> c; Array<TYPE, FUN, Allocator> c;
FUN::multiply(a, b, c); FUN::multiply(a, b, c);
return c; return c;
} }
template <class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator>
inline Array<TYPE, FUN, Allocator> operator*( inline Array<TYPE, FUN, Allocator>
const Array<TYPE, FUN, Allocator> &a, const std::vector<TYPE> &b ) operator*(const Array<TYPE, FUN, Allocator> &a, const std::vector<TYPE> &b) {
{
Array<TYPE, FUN, Allocator> b2, c; Array<TYPE, FUN, Allocator> b2, c;
b2.viewRaw({b.size()}, const_cast<TYPE *>(b.data())); b2.viewRaw({b.size()}, const_cast<TYPE *>(b.data()));
FUN::multiply(a, b2, c); FUN::multiply(a, b2, c);
return c; return c;
} }
template <class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator>
inline Array<TYPE, FUN, Allocator> operator*( const TYPE &a, inline Array<TYPE, FUN, Allocator>
const Array<TYPE, FUN, Allocator> &b ) operator*(const TYPE &a, const Array<TYPE, FUN, Allocator> &b) {
{
auto c = b; auto c = b;
c.scale(a); c.scale(a);
return c; return c;
} }
template <class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator>
inline Array<TYPE, FUN, Allocator> operator*( const Array<TYPE, FUN, Allocator> &a, inline Array<TYPE, FUN, Allocator>
const TYPE &b ) operator*(const Array<TYPE, FUN, Allocator> &a, const TYPE &b) {
{
auto c = a; auto c = a;
c.scale(b); c.scale(b);
return c; return c;
} }
/******************************************************** /********************************************************
* Copy array * * Copy array *
********************************************************/ ********************************************************/
template <class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator>
template <class TYPE2> 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) { if (std::is_same<TYPE, TYPE2>::value) {
std::copy(data, data + d_size.length(), d_data); std::copy(data, data + d_size.length(), d_data);
} else { } else {
@ -900,8 +856,7 @@ inline void Array<TYPE, FUN, Allocator>::copy( const TYPE2 *data )
} }
template <class TYPE, class FUN, class Allocator> template <class TYPE, class FUN, class Allocator>
template <class TYPE2> 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) { if (std::is_same<TYPE, TYPE2>::value) {
std::copy(d_data, d_data + d_size.length(), data); std::copy(d_data, d_data + d_size.length(), data);
} else { } else {
@ -910,7 +865,6 @@ inline void Array<TYPE, FUN, Allocator>::copyTo( TYPE2 *data ) const
} }
} }
/******************************************************** /********************************************************
* Convience typedefs * * Convience typedefs *
* Copy array * * Copy array *
@ -918,5 +872,4 @@ inline void Array<TYPE, FUN, Allocator>::copyTo( TYPE2 *data ) const
typedef Array<double> DoubleArray; typedef Array<double> DoubleArray;
typedef Array<int> IntArray; typedef Array<int> IntArray;
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,6 @@
#include <initializer_list> #include <initializer_list>
#include <vector> #include <vector>
#if defined(__CUDA_ARCH__) #if defined(__CUDA_ARCH__)
#include <cuda.h> #include <cuda.h>
#define HOST_DEVICE __host__ __device__ #define HOST_DEVICE __host__ __device__
@ -24,7 +23,6 @@
#define ARRAY_ATTRIBUTE HOST_DEVICE #define ARRAY_ATTRIBUTE HOST_DEVICE
#endif #endif
#if (defined(DEBUG) || defined(_DEBUG)) && !defined(NDEBUG) #if (defined(DEBUG) || defined(_DEBUG)) && !defined(NDEBUG)
#define CHECK_ARRAY_LENGTH(i, length) \ #define CHECK_ARRAY_LENGTH(i, length) \
do { \ do { \
@ -37,18 +35,14 @@
} while (0) } while (0)
#endif #endif
// Forward declerations // Forward declerations
class FunctionTable; 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; class Array;
//! Simple range class //! Simple range class
template<class TYPE = size_t> template <class TYPE = size_t> class Range final {
class Range final
{
public: public:
//! Empty constructor //! Empty constructor
Range() : i(0), j(-1), k(1) {} Range() : i(0), j(-1), k(1) {}
@ -60,13 +54,10 @@ public:
* @param k_ Increment value * @param k_ Increment value
*/ */
Range(const TYPE &i_, const TYPE &j_, const TYPE &k_ = 1) 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 //! Get the number of values in the range
size_t size() const size_t size() const {
{
if (std::is_integral<TYPE>::value) { if (std::is_integral<TYPE>::value) {
return (static_cast<int64_t>(j) - static_cast<int64_t>(i)) / return (static_cast<int64_t>(j) - static_cast<int64_t>(i)) /
static_cast<int64_t>(k); static_cast<int64_t>(k);
@ -86,10 +77,8 @@ public:
TYPE i, j, k; TYPE i, j, k;
}; };
//! Simple class to store the array dimensions //! Simple class to store the array dimensions
class ArraySize final class ArraySize final {
{
public: public:
//! Empty constructor //! Empty constructor
ArraySize() : d_ndim(1), d_length(0), d_N{0, 1, 1, 1, 1} {} ArraySize() : d_ndim(1), d_length(0), d_N{0, 1, 1, 1, 1} {}
@ -106,9 +95,7 @@ public:
* @param N2 Number of elements in the second dimension * @param N2 Number of elements in the second dimension
*/ */
ArraySize(size_t N1, size_t N2) 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 * Create the vector size
@ -117,9 +104,7 @@ public:
* @param N3 Number of elements in the third dimension * @param N3 Number of elements in the third dimension
*/ */
ArraySize(size_t N1, size_t N2, size_t N3) 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 * Create the vector size
@ -129,9 +114,7 @@ public:
* @param N4 Number of elements in the fourth dimension * @param N4 Number of elements in the fourth dimension
*/ */
ArraySize(size_t N1, size_t N2, size_t N3, size_t N4) 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 * Create the vector size
@ -142,8 +125,7 @@ public:
* @param N5 Number of elements in the fifth dimension * @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) 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} {
{
} }
/*! /*!
@ -152,8 +134,7 @@ public:
* @param ndim Number of dimensions * @param ndim Number of dimensions
*/ */
ArraySize(std::initializer_list<size_t> N, int ndim = -1) 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) if (ndim >= 0)
d_ndim = ndim; d_ndim = ndim;
if (d_ndim > 5) if (d_ndim > 5)
@ -168,15 +149,13 @@ public:
d_length = 0; d_length = 0;
} }
/*! /*!
* Create from raw pointer * Create from raw pointer
* @param ndim Number of dimensions * @param ndim Number of dimensions
* @param dims Dimensions * @param dims Dimensions
*/ */
ArraySize(size_t ndim, const size_t *dims) 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) if (d_ndim > 5)
throw std::out_of_range("Maximum number of dimensions exceeded"); throw std::out_of_range("Maximum number of dimensions exceeded");
for (size_t i = 0; i < ndim; i++) for (size_t i = 0; i < ndim; i++)
@ -193,15 +172,14 @@ public:
* @param N Size of the array * @param N Size of the array
*/ */
template <std::size_t NDIM> 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 * Create from std::vector
* @param N Size of the array * @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 // Copy/assignment constructors
ArraySize(ArraySize &&rhs) = default; ArraySize(ArraySize &&rhs) = default;
@ -225,8 +203,7 @@ public:
ARRAY_ATTRIBUTE size_t length() const { return d_length; } ARRAY_ATTRIBUTE size_t length() const { return d_length; }
//! Resize the dimension //! Resize the dimension
void resize( uint8_t dim, size_t N ) void resize(uint8_t dim, size_t N) {
{
if (dim >= d_ndim) if (dim >= d_ndim)
throw std::out_of_range("Invalid dimension"); throw std::out_of_range("Invalid dimension");
d_N[dim] = N; d_N[dim] = N;
@ -245,8 +222,7 @@ public:
/*! /*!
* Remove singleton dimensions * Remove singleton dimensions
*/ */
void squeeze() void squeeze() {
{
d_ndim = 0; d_ndim = 0;
for (uint8_t i = 0; i < maxDim(); i++) { for (uint8_t i = 0; i < maxDim(); i++) {
if (d_N[i] != 1) if (d_N[i] != 1)
@ -261,20 +237,18 @@ public:
const size_t *end() const { return d_N + d_ndim; } const size_t *end() const { return d_N + d_ndim; }
// Check if two array sizes are equal // 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; 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) // Check if two array sizes are equal (ignoring the dimension)
ARRAY_ATTRIBUTE bool approxEqual( const ArraySize &rhs ) const ARRAY_ATTRIBUTE bool approxEqual(const ArraySize &rhs) const {
{ return (length() == 0 && rhs.length() == 0) ||
return ( length() == 0 && rhs.length() == 0 ) || memcmp( d_N, rhs.d_N, sizeof( d_N ) ) == 0; memcmp(d_N, rhs.d_N, sizeof(d_N)) == 0;
} }
//! Check if two matrices are not equal //! 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; return d_ndim != rhs.d_ndim || memcmp(d_N, rhs.d_N, sizeof(d_N)) != 0;
} }
@ -282,48 +256,44 @@ public:
ARRAY_ATTRIBUTE static uint8_t maxDim() { return 5; } ARRAY_ATTRIBUTE static uint8_t maxDim() { return 5; }
//! Get the index //! 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); CHECK_ARRAY_LENGTH(i, d_length);
return i; return i;
} }
//! Get the index //! 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]; size_t index = i1 + i2 * d_N[0];
CHECK_ARRAY_LENGTH(index, d_length); CHECK_ARRAY_LENGTH(index, d_length);
return index; return index;
} }
//! Get the 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); size_t index = i1 + d_N[0] * (i2 + d_N[1] * i3);
CHECK_ARRAY_LENGTH(index, d_length); CHECK_ARRAY_LENGTH(index, d_length);
return index; return index;
} }
//! Get the 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)); size_t index = i1 + d_N[0] * (i2 + d_N[1] * (i3 + d_N[2] * i4));
CHECK_ARRAY_LENGTH(index, d_length); CHECK_ARRAY_LENGTH(index, d_length);
return index; return index;
} }
//! Get the index //! Get the index
ARRAY_ATTRIBUTE size_t ARRAY_ATTRIBUTE size_t index(size_t i1, size_t i2, size_t i3, size_t i4,
index( size_t i1, size_t i2, size_t i3, size_t i4, size_t i5 ) const size_t i5) const {
{ size_t index =
size_t index = i1 + d_N[0] * ( i2 + d_N[1] * ( i3 + d_N[2] * ( i4 + d_N[3] * i5 ) ) ); i1 + d_N[0] * (i2 + d_N[1] * (i3 + d_N[2] * (i4 + d_N[3] * i5)));
CHECK_ARRAY_LENGTH(index, d_length); CHECK_ARRAY_LENGTH(index, d_length);
return index; return index;
} }
//! Get the 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; size_t j = 0;
for (size_t m = 0, N = 1; m < 5; m++) { for (size_t m = 0, N = 1; m < 5; m++) {
j += i[m] * N; j += i[m] * N;
@ -333,8 +303,7 @@ public:
} }
//! Get the index //! 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 N = 1;
size_t j = 0; size_t j = 0;
size_t m = 0; size_t m = 0;
@ -346,8 +315,7 @@ public:
} }
//! Convert the index to ijk values //! 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); CHECK_ARRAY_LENGTH(index, d_length);
size_t i0 = index % d_N[0]; size_t i0 = index % d_N[0];
index = index / d_N[0]; index = index / d_N[0];
@ -361,8 +329,7 @@ public:
} }
//! Convert the index to ijk values //! 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); CHECK_ARRAY_LENGTH(index, d_length);
x[0] = index % d_N[0]; x[0] = index % d_N[0];
index = index / d_N[0]; index = index / d_N[0];
@ -381,10 +348,8 @@ private:
size_t d_N[5]; size_t d_N[5];
}; };
// Function to concatenate dimensions of two array sizes // 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) if (x.ndim() + y.ndim() > 5)
throw std::out_of_range("Maximum number of dimensions exceeded"); throw std::out_of_range("Maximum number of dimensions exceeded");
size_t N[5] = {0}; size_t N[5] = {0};
@ -395,30 +360,24 @@ inline ArraySize cat( const ArraySize &x, const ArraySize &y )
return ArraySize(x.ndim() + y.ndim(), N); return ArraySize(x.ndim() + y.ndim(), N);
} }
// Operator overloads // 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]}; size_t N[5] = {v * x[0], v * x[1], v * x[2], v * x[3], v * x[4]};
return ArraySize(x.ndim(), N); 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]}; size_t N[5] = {v * x[0], v * x[1], v * x[2], v * x[3], v * x[4]};
return ArraySize(x.ndim(), N); 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}; size_t N[5] = {x[0] - v, x[1] - v, x[2] - v, x[3] - v, x[4] - v};
return ArraySize(x.ndim(), N); 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}; size_t N[5] = {x[0] + v, x[1] + v, x[2] + v, x[3] + v, x[4] + v};
return ArraySize(x.ndim(), N); 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}; size_t N[5] = {x[0] + v, x[1] + v, x[2] + v, x[3] + v, x[4] + v};
return ArraySize(x.ndim(), N); return ArraySize(x.ndim(), N);
} }
@ -427,5 +386,4 @@ inline ArraySize operator+( size_t v, const ArraySize &x )
ENABLE_WARNINGS ENABLE_WARNINGS
#endif #endif
#endif #endif

View File

@ -16,19 +16,16 @@
*/ */
#include "common/Communication.h" #include "common/Communication.h"
/******************************************************** /********************************************************
* Structure to store the rank info * * 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 i2 = (i + nx) % nx;
int j2 = (j + ny) % ny; int j2 = (j + ny) % ny;
int k2 = (k + nz) % nz; int k2 = (k + nz) % nz;
return i2 + j2 * nx + k2 * nx * ny; return i2 + j2 * nx + k2 * nx * ny;
} }
RankInfoStruct::RankInfoStruct() RankInfoStruct::RankInfoStruct() {
{
nx = 0; nx = 0;
ny = 0; ny = 0;
nz = 0; nz = 0;
@ -43,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)); memset(this, 0, sizeof(RankInfoStruct));
nx = nprocx; nx = nprocx;
ny = nprocy; ny = nprocy;
@ -67,7 +63,8 @@ RankInfoStruct::RankInfoStruct( int rank0, int nprocx, int nprocy, int nprocz )
for (int i = -1; i <= 1; i++) { for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) { for (int j = -1; j <= 1; j++) {
for (int k = -1; k <= 1; k++) { 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);
} }
} }
} }
@ -75,18 +72,16 @@ RankInfoStruct::RankInfoStruct( int rank0, int nprocx, int nprocy, int nprocz )
} }
} }
/******************************************************** /********************************************************
* Deprecated functions * * Deprecated functions *
********************************************************/ ********************************************************/
void InitializeRanks( const int rank, const int nprocx, const int nprocy, const int nprocz, void InitializeRanks(const int rank, const int nprocx, const int nprocy,
int& iproc, int& jproc, int& kproc, 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_X,
int& rank_X, int& rank_Y, int& rank_Z, int &rank_Y, int &rank_Z, int &rank_xy, int &rank_XY,
int& rank_xy, int& rank_XY, 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_xZ, int& rank_Xz, int &rank_xZ, int &rank_Xz, int &rank_yz, int &rank_YZ,
int& rank_yz, int& rank_YZ, int& rank_yZ, int& rank_Yz ) int &rank_yZ, int &rank_Yz) {
{
const RankInfoStruct data(rank, nprocx, nprocy, nprocz); const RankInfoStruct data(rank, nprocx, nprocy, nprocz);
iproc = data.ix; iproc = data.ix;
jproc = data.jy; jproc = data.jy;
@ -110,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][2][0];
rank_yZ = data.rank[1][0][2]; rank_yZ = data.rank[1][0][2];
} }

View File

@ -32,7 +32,6 @@
using namespace std; using namespace std;
/*! /*!
* @brief Rank info structure * @brief Rank info structure
* @details Structure used to hold the ranks for the current process and it's neighbors * @details Structure used to hold the ranks for the current process and it's neighbors
@ -50,20 +49,18 @@ struct RankInfoStruct {
int getRankForBlock(int i, int j, int k) const; int getRankForBlock(int i, int j, int k) const;
}; };
//! Redistribute domain data (dst may be smaller than the src) //! Redistribute domain data (dst may be smaller than the src)
template <class TYPE> template <class TYPE>
Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src_data, Array<TYPE>
const RankInfoStruct& dst_rank, std::array<int,3> dst_size, const Utilities::MPI& comm ); 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 * @brief Communicate halo
* @details Fill the halo cells in an array from the neighboring processes * @details Fill the halo cells in an array from the neighboring processes
*/ */
template<class TYPE> template <class TYPE> class fillHalo {
class fillHalo
{
public: public:
/*! /*!
* @brief Default constructor * @brief Default constructor
@ -102,7 +99,6 @@ public:
template <class TYPE1, class TYPE2> template <class TYPE1, class TYPE2>
void copy(const Array<TYPE1> &src, Array<TYPE2> &dst); void copy(const Array<TYPE1> &src, Array<TYPE2> &dst);
private: private:
Utilities::MPI comm; Utilities::MPI comm;
RankInfoStruct info; RankInfoStruct info;
@ -118,9 +114,9 @@ private:
void unpack(Array<TYPE> &array, int i, int j, int k, const TYPE *buffer); 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 // Fill in the phase ID values from neighboring processors
// This packs up the values that need to be sent from one processor to another // This packs up the values that need to be sent from one processor to another
int idx, n; int idx, n;
@ -129,7 +125,8 @@ inline void PackMeshData(const int *list, int count, double *sendbuf, double *da
sendbuf[idx] = data[n]; 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 // Fill in the phase ID values from neighboring processors
// This unpacks the values once they have been recieved from neighbors // This unpacks the values once they have been recieved from neighbors
int idx, n; int idx, n;
@ -140,35 +137,31 @@ inline void UnpackMeshData(const int *list, int count, double *recvbuf, double *
} }
} }
// Initialize the ranks (this is deprecated, see RankInfoStruct) // Initialize the ranks (this is deprecated, see RankInfoStruct)
void InitializeRanks( const int rank, const int nprocx, const int nprocy, const int nprocz, void InitializeRanks(const int rank, const int nprocx, const int nprocy,
int& iproc, int& jproc, int& kproc, 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_X,
int& rank_X, int& rank_Y, int& rank_Z, int &rank_Y, int &rank_Z, int &rank_xy, int &rank_XY,
int& rank_xy, int& rank_XY, 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_xZ, int& rank_Xz, int &rank_xZ, int &rank_Xz, int &rank_yz, int &rank_YZ,
int& rank_yz, int& rank_YZ, int& rank_yZ, int& rank_Yz ); int &rank_yZ, int &rank_Yz);
//*************************************************************************************** //***************************************************************************************
inline void CommunicateSendRecvCounts( const Utilities::MPI& comm, int sendtag, int recvtag, inline void CommunicateSendRecvCounts(
int rank_x, int rank_y, int rank_z, const Utilities::MPI &comm, int sendtag, int recvtag, int rank_x,
int rank_X, int rank_Y, int rank_Z, 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_Xy, int rank_XY, int rank_xY, int rank_Xy, int rank_xz, int rank_XZ,
int rank_xz, int rank_XZ, 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 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_X, int sendCount_Y, int sendCount_Z, int sendCount_xy,
int sendCount_X, int sendCount_Y, int sendCount_Z, int sendCount_XY, int sendCount_xY, int sendCount_Xy, int sendCount_xz,
int sendCount_xy, int sendCount_XY, int sendCount_xY, int sendCount_Xy, int sendCount_XZ, int sendCount_xZ, int sendCount_Xz, int sendCount_yz,
int sendCount_xz, int sendCount_XZ, int sendCount_xZ, int sendCount_Xz, int sendCount_YZ, int sendCount_yZ, int sendCount_Yz, int &recvCount_x,
int sendCount_yz, int sendCount_YZ, int sendCount_yZ, int sendCount_Yz, int &recvCount_y, int &recvCount_z, int &recvCount_X, int &recvCount_Y,
int& recvCount_x, int& recvCount_y, int& recvCount_z, int &recvCount_Z, int &recvCount_xy, int &recvCount_XY, int &recvCount_xY,
int& recvCount_X, int& recvCount_Y, int& recvCount_Z, int &recvCount_Xy, int &recvCount_xz, int &recvCount_XZ, int &recvCount_xZ,
int& recvCount_xy, int& recvCount_XY, int& recvCount_xY, int& recvCount_Xy, int &recvCount_Xz, int &recvCount_yz, int &recvCount_YZ, int &recvCount_yZ,
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& recvCount_Yz )
{
MPI_Request req1[18], req2[18]; MPI_Request req1[18], req2[18];
req1[0] = comm.Isend(&sendCount_x, 1, rank_x, sendtag + 0); req1[0] = comm.Isend(&sendCount_x, 1, rank_x, sendtag + 0);
req2[0] = comm.Irecv(&recvCount_X, 1, rank_X, recvtag + 0); req2[0] = comm.Irecv(&recvCount_X, 1, rank_X, recvtag + 0);
@ -214,28 +207,31 @@ inline void CommunicateSendRecvCounts( const Utilities::MPI& comm, int sendtag,
comm.barrier(); comm.barrier();
} }
//*************************************************************************************** //***************************************************************************************
inline void CommunicateRecvLists( const Utilities::MPI& comm, int sendtag, int recvtag, inline void CommunicateRecvLists(
int *sendList_x, int *sendList_y, int *sendList_z, int *sendList_X, int *sendList_Y, int *sendList_Z, const Utilities::MPI &comm, int sendtag, int recvtag, int *sendList_x,
int *sendList_xy, int *sendList_XY, int *sendList_xY, int *sendList_Xy, int *sendList_y, int *sendList_z, int *sendList_X, int *sendList_Y,
int *sendList_xz, int *sendList_XZ, int *sendList_xZ, int *sendList_Xz, int *sendList_Z, int *sendList_xy, int *sendList_XY, int *sendList_xY,
int *sendList_yz, int *sendList_YZ, int *sendList_yZ, int *sendList_Yz, int *sendList_Xy, int *sendList_xz, int *sendList_XZ, int *sendList_xZ,
int sendCount_x, int sendCount_y, int sendCount_z, int sendCount_X, int sendCount_Y, int sendCount_Z, int *sendList_Xz, int *sendList_yz, int *sendList_YZ, int *sendList_yZ,
int sendCount_xy, int sendCount_XY, int sendCount_xY, int sendCount_Xy, int *sendList_Yz, int sendCount_x, int sendCount_y, int sendCount_z,
int sendCount_xz, int sendCount_XZ, int sendCount_xZ, int sendCount_Xz, int sendCount_X, int sendCount_Y, int sendCount_Z, int sendCount_xy,
int sendCount_yz, int sendCount_YZ, int sendCount_yZ, int sendCount_Yz, int sendCount_XY, int sendCount_xY, int sendCount_Xy, int sendCount_xz,
int *recvList_x, int *recvList_y, int *recvList_z, int *recvList_X, int *recvList_Y, int *recvList_Z, int sendCount_XZ, int sendCount_xZ, int sendCount_Xz, int sendCount_yz,
int *recvList_xy, int *recvList_XY, int *recvList_xY, int *recvList_Xy, int sendCount_YZ, int sendCount_yZ, int sendCount_Yz, int *recvList_x,
int *recvList_xz, int *recvList_XZ, int *recvList_xZ, int *recvList_Xz, int *recvList_y, int *recvList_z, int *recvList_X, int *recvList_Y,
int *recvList_yz, int *recvList_YZ, int *recvList_yZ, int *recvList_Yz, int *recvList_Z, int *recvList_xy, int *recvList_XY, int *recvList_xY,
int recvCount_x, int recvCount_y, int recvCount_z, int recvCount_X, int recvCount_Y, int recvCount_Z, int *recvList_Xy, int *recvList_xz, int *recvList_XZ, int *recvList_xZ,
int recvCount_xy, int recvCount_XY, int recvCount_xY, int recvCount_Xy, int *recvList_Xz, int *recvList_yz, int *recvList_YZ, int *recvList_yZ,
int recvCount_xz, int recvCount_XZ, int recvCount_xZ, int recvCount_Xz, int *recvList_Yz, int recvCount_x, int recvCount_y, int recvCount_z,
int recvCount_yz, int recvCount_YZ, int recvCount_yZ, int recvCount_Yz, int recvCount_X, int recvCount_Y, int recvCount_Z, int recvCount_xy,
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 recvCount_XY, int recvCount_xY, int recvCount_Xy, int recvCount_xz,
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_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) {
MPI_Request req1[18], req2[18]; MPI_Request req1[18], req2[18];
req1[0] = comm.Isend(sendList_x, sendCount_x, rank_x, sendtag); req1[0] = comm.Isend(sendList_x, sendCount_x, rank_x, sendtag);
req2[0] = comm.Irecv(recvList_X, recvCount_X, rank_X, recvtag); req2[0] = comm.Irecv(recvList_X, recvCount_X, rank_X, recvtag);
@ -280,36 +276,41 @@ inline void CommunicateRecvLists( const Utilities::MPI& comm, int sendtag, int r
comm.waitAll(18, req2); comm.waitAll(18, req2);
} }
//*************************************************************************************** //***************************************************************************************
inline void CommunicateMeshHalo(DoubleArray &Mesh, const Utilities::MPI& comm, inline void CommunicateMeshHalo(
double *sendbuf_x,double *sendbuf_y,double *sendbuf_z,double *sendbuf_X,double *sendbuf_Y,double *sendbuf_Z, DoubleArray &Mesh, const Utilities::MPI &comm, double *sendbuf_x,
double *sendbuf_xy,double *sendbuf_XY,double *sendbuf_xY,double *sendbuf_Xy, double *sendbuf_y, double *sendbuf_z, double *sendbuf_X, double *sendbuf_Y,
double *sendbuf_xz,double *sendbuf_XZ,double *sendbuf_xZ,double *sendbuf_Xz, double *sendbuf_Z, double *sendbuf_xy, double *sendbuf_XY,
double *sendbuf_yz,double *sendbuf_YZ,double *sendbuf_yZ,double *sendbuf_Yz, double *sendbuf_xY, double *sendbuf_Xy, double *sendbuf_xz,
double *recvbuf_x,double *recvbuf_y,double *recvbuf_z,double *recvbuf_X,double *recvbuf_Y,double *recvbuf_Z, double *sendbuf_XZ, double *sendbuf_xZ, double *sendbuf_Xz,
double *recvbuf_xy,double *recvbuf_XY,double *recvbuf_xY,double *recvbuf_Xy, double *sendbuf_yz, double *sendbuf_YZ, double *sendbuf_yZ,
double *recvbuf_xz,double *recvbuf_XZ,double *recvbuf_xZ,double *recvbuf_Xz, double *sendbuf_Yz, double *recvbuf_x, double *recvbuf_y, double *recvbuf_z,
double *recvbuf_yz,double *recvbuf_YZ,double *recvbuf_yZ,double *recvbuf_Yz, double *recvbuf_X, double *recvbuf_Y, double *recvbuf_Z, double *recvbuf_xy,
int *sendList_x,int *sendList_y,int *sendList_z,int *sendList_X,int *sendList_Y,int *sendList_Z, 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_xy, int *sendList_XY, int *sendList_xY, int *sendList_Xy,
int *sendList_xz, int *sendList_XZ, int *sendList_xZ, int *sendList_Xz, 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 *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_x, int sendCount_y, int sendCount_z, int sendCount_X,
int sendCount_xy,int sendCount_XY,int sendCount_xY,int sendCount_Xy, int sendCount_Y, int sendCount_Z, int sendCount_xy, int sendCount_XY,
int sendCount_xz,int sendCount_XZ,int sendCount_xZ,int sendCount_Xz, int sendCount_xY, int sendCount_Xy, int sendCount_xz, int sendCount_XZ,
int sendCount_yz,int sendCount_YZ,int sendCount_yZ,int sendCount_Yz, int sendCount_xZ, int sendCount_Xz, 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_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_xy, int *recvList_XY, int *recvList_xY, int *recvList_Xy,
int *recvList_xz, int *recvList_XZ, int *recvList_xZ, int *recvList_Xz, 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 *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_x, int recvCount_y, int recvCount_z, int recvCount_X,
int recvCount_xy,int recvCount_XY,int recvCount_xY,int recvCount_Xy, int recvCount_Y, int recvCount_Z, int recvCount_xy, int recvCount_XY,
int recvCount_xz,int recvCount_XZ,int recvCount_xZ,int recvCount_Xz, int recvCount_xY, int recvCount_Xy, int recvCount_xz, int recvCount_XZ,
int recvCount_yz,int recvCount_YZ,int recvCount_yZ,int recvCount_Yz, int recvCount_xZ, int recvCount_Xz, 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 recvCount_yZ, int recvCount_Yz, int rank_x, int rank_y, int rank_z,
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 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; int sendtag, recvtag;
sendtag = recvtag = 7; sendtag = recvtag = 7;
double *MeshData = Mesh.data(); double *MeshData = Mesh.data();
@ -332,24 +333,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);
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,
comm.sendrecv(sendbuf_X,sendCount_X,rank_X,sendtag,recvbuf_x,recvCount_x,rank_x,recvtag); recvCount_X, rank_X, recvtag);
comm.sendrecv(sendbuf_y,sendCount_y,rank_y,sendtag,recvbuf_Y,recvCount_Y,rank_Y,recvtag); comm.sendrecv(sendbuf_X, sendCount_X, rank_X, sendtag, recvbuf_x,
comm.sendrecv(sendbuf_Y,sendCount_Y,rank_Y,sendtag,recvbuf_y,recvCount_y,rank_y,recvtag); recvCount_x, rank_x, recvtag);
comm.sendrecv(sendbuf_z,sendCount_z,rank_z,sendtag,recvbuf_Z,recvCount_Z,rank_Z,recvtag); comm.sendrecv(sendbuf_y, sendCount_y, rank_y, sendtag, recvbuf_Y,
comm.sendrecv(sendbuf_Z,sendCount_Z,rank_Z,sendtag,recvbuf_z,recvCount_z,rank_z,recvtag); recvCount_Y, rank_Y, recvtag);
comm.sendrecv(sendbuf_xy,sendCount_xy,rank_xy,sendtag,recvbuf_XY,recvCount_XY,rank_XY,recvtag); comm.sendrecv(sendbuf_Y, sendCount_Y, rank_Y, sendtag, recvbuf_y,
comm.sendrecv(sendbuf_XY,sendCount_XY,rank_XY,sendtag,recvbuf_xy,recvCount_xy,rank_xy,recvtag); recvCount_y, rank_y, recvtag);
comm.sendrecv(sendbuf_Xy,sendCount_Xy,rank_Xy,sendtag,recvbuf_xY,recvCount_xY,rank_xY,recvtag); comm.sendrecv(sendbuf_z, sendCount_z, rank_z, sendtag, recvbuf_Z,
comm.sendrecv(sendbuf_xY,sendCount_xY,rank_xY,sendtag,recvbuf_Xy,recvCount_Xy,rank_Xy,recvtag); recvCount_Z, rank_Z, recvtag);
comm.sendrecv(sendbuf_xz,sendCount_xz,rank_xz,sendtag,recvbuf_XZ,recvCount_XZ,rank_XZ,recvtag); comm.sendrecv(sendbuf_Z, sendCount_Z, rank_Z, sendtag, recvbuf_z,
comm.sendrecv(sendbuf_XZ,sendCount_XZ,rank_XZ,sendtag,recvbuf_xz,recvCount_xz,rank_xz,recvtag); recvCount_z, rank_z, recvtag);
comm.sendrecv(sendbuf_Xz,sendCount_Xz,rank_Xz,sendtag,recvbuf_xZ,recvCount_xZ,rank_xZ,recvtag); comm.sendrecv(sendbuf_xy, sendCount_xy, rank_xy, sendtag, recvbuf_XY,
comm.sendrecv(sendbuf_xZ,sendCount_xZ,rank_xZ,sendtag,recvbuf_Xz,recvCount_Xz,rank_Xz,recvtag); recvCount_XY, rank_XY, recvtag);
comm.sendrecv(sendbuf_yz,sendCount_yz,rank_yz,sendtag,recvbuf_YZ,recvCount_YZ,rank_YZ,recvtag); comm.sendrecv(sendbuf_XY, sendCount_XY, rank_XY, sendtag, recvbuf_xy,
comm.sendrecv(sendbuf_YZ,sendCount_YZ,rank_YZ,sendtag,recvbuf_yz,recvCount_yz,rank_yz,recvtag); recvCount_xy, rank_xy, recvtag);
comm.sendrecv(sendbuf_Yz,sendCount_Yz,rank_Yz,sendtag,recvbuf_yZ,recvCount_yZ,rank_yZ,recvtag); comm.sendrecv(sendbuf_Xy, sendCount_Xy, rank_Xy, sendtag, recvbuf_xY,
comm.sendrecv(sendbuf_yZ,sendCount_yZ,rank_yZ,sendtag,recvbuf_Yz,recvCount_Yz,rank_Yz,recvtag); 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);
UnpackMeshData(recvList_X, recvCount_X, recvbuf_X, MeshData); UnpackMeshData(recvList_X, recvCount_X, recvbuf_X, MeshData);
@ -371,9 +390,6 @@ inline void CommunicateMeshHalo(DoubleArray &Mesh, const Utilities::MPI& comm,
UnpackMeshData(recvList_YZ, recvCount_YZ, recvbuf_YZ, MeshData); UnpackMeshData(recvList_YZ, recvCount_YZ, recvbuf_YZ, MeshData);
} }
#endif #endif
#include "common/Communication.hpp" #include "common/Communication.hpp"

View File

@ -37,30 +37,36 @@
#include "common/MPI.h" #include "common/MPI.h"
#include "common/Utilities.h" #include "common/Utilities.h"
/******************************************************** /********************************************************
* Redistribute data between two grids * * Redistribute data between two grids *
********************************************************/ ********************************************************/
template <class TYPE> template <class TYPE>
Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src_data, Array<TYPE>
const RankInfoStruct& dst_rank, std::array<int,3> dst_size, const Utilities::MPI& comm ) 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) { 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 // Get the src size
std::array<int, 3> 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); comm.maxReduce(size0, src_size.data(), 3);
if (!src_data.empty()) 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 // Check that dst_size matches on all ranks
comm.maxReduce(dst_size.data(), size0, 3); 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 // Function to get overlap range
auto calcOverlap = [](int i1[3], int i2[3], int j1[3], int j2[3]) { auto calcOverlap = [](int i1[3], int i2[3], int j1[3], int j2[3]) {
std::vector<size_t> index; 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; return index;
index.resize(6); index.resize(6);
index[0] = std::max(j1[0] - i1[0], 0); index[0] = std::max(j1[0] - i1[0], 0);
@ -75,13 +81,18 @@ Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src
std::vector<int> send_rank; std::vector<int> send_rank;
std::vector<Array<TYPE>> send_data; std::vector<Array<TYPE>> send_data;
if (!src_data.empty()) { 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 i1[3] = {src_size[0] * src_rank.ix, src_size[1] * src_rank.jy,
int i2[3] = { i1[0] + src_size[0] - 1, i1[1] + src_size[1] - 1, i1[2] + src_size[2] - 1 }; 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 i = 0; i < dst_rank.nx; i++) {
for (int j = 0; j < dst_rank.ny; j++) { for (int j = 0; j < dst_rank.ny; j++) {
for (int k = 0; k < dst_rank.nz; k++) { 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 j1[3] = {i * dst_size[0], j * dst_size[1],
int j2[3] = { j1[0] + dst_size[0] - 1, j1[1] + dst_size[1] - 1, j1[2] + dst_size[2] - 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); auto index = calcOverlap(i1, i2, j1, j2);
if (index.empty()) if (index.empty())
continue; continue;
@ -93,21 +104,27 @@ Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src
} }
std::vector<MPI_Request> send_request(send_rank.size()); std::vector<MPI_Request> send_request(send_rank.size());
for (size_t i = 0; i < send_rank.size(); i++) 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) // Unpack data from the appropriate ranks (including myself)
Array<TYPE> dst_data(dst_size[0], dst_size[1], dst_size[2]); 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 i1[3] = {dst_size[0] * dst_rank.ix, dst_size[1] * dst_rank.jy,
int i2[3] = { i1[0] + dst_size[0] - 1, i1[1] + dst_size[1] - 1, i1[2] + dst_size[2] - 1 }; 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 i = 0; i < src_rank.nx; i++) {
for (int j = 0; j < src_rank.ny; j++) { for (int j = 0; j < src_rank.ny; j++) {
for (int k = 0; k < src_rank.nz; k++) { 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 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); auto index = calcOverlap(i1, i2, j1, j2);
if (index.empty()) if (index.empty())
continue; continue;
int rank = src_rank.getRankForBlock(i, j, k); 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); comm.recv(data.data(), data.length(), rank, 5462);
dst_data.copySubset(index, data); dst_data.copySubset(index, data);
} }
@ -118,17 +135,15 @@ Array<TYPE> redistribute( const RankInfoStruct& src_rank, const Array<TYPE>& src
return dst_data; return dst_data;
} }
/******************************************************** /********************************************************
* Structure to fill halo cells * * Structure to fill halo cells *
********************************************************/ ********************************************************/
template <class TYPE> template <class TYPE>
fillHalo<TYPE>::fillHalo( const Utilities::MPI& comm_, const RankInfoStruct& info_, fillHalo<TYPE>::fillHalo(const Utilities::MPI &comm_,
std::array<int,3> n_, std::array<int,3> ng_, int tag0, int depth_, const RankInfoStruct &info_, std::array<int, 3> n_,
std::array<bool,3> fill, std::array<bool,3> periodic ): std::array<int, 3> ng_, int tag0, int depth_,
comm(comm_), info(info_), n(n_), ng(ng_), depth(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 // Set the fill pattern
memset(fill_pattern, 0, sizeof(fill_pattern)); memset(fill_pattern, 0, sizeof(fill_pattern));
if (fill[0]) { if (fill[0]) {
@ -242,16 +257,9 @@ fillHalo<TYPE>::fillHalo( const Utilities::MPI& comm_, const RankInfoStruct& inf
} }
} }
} }
} }
template<class TYPE> template <class TYPE> fillHalo<TYPE>::~fillHalo() { delete[] mem; }
fillHalo<TYPE>::~fillHalo( ) template <class TYPE> void fillHalo<TYPE>::fill(Array<TYPE> &data) {
{
delete [] mem;
}
template<class TYPE>
void fillHalo<TYPE>::fill( Array<TYPE>& data )
{
//PROFILE_START("fillHalo::fill",1); //PROFILE_START("fillHalo::fill",1);
int depth2 = data.size(3); int depth2 = data.size(3);
ASSERT((int)data.size(0) == n[0] + 2 * ng[0]); ASSERT((int)data.size(0) == n[0] + 2 * ng[0]);
@ -265,7 +273,8 @@ void fillHalo<TYPE>::fill( Array<TYPE>& data )
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
if (!fill_pattern[i][j][k]) if (!fill_pattern[i][j][k])
continue; 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]); info.rank[i][j][k], tag[2 - i][2 - j][2 - k]);
} }
} }
@ -277,7 +286,8 @@ void fillHalo<TYPE>::fill( Array<TYPE>& data )
if (!fill_pattern[i][j][k]) if (!fill_pattern[i][j][k])
continue; continue;
pack(data, i - 1, j - 1, k - 1, send[i][j][k]); 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]); info.rank[i][j][k], tag[i][j][k]);
} }
} }
@ -306,8 +316,8 @@ void fillHalo<TYPE>::fill( Array<TYPE>& data )
//PROFILE_STOP("fillHalo::fill",1); //PROFILE_STOP("fillHalo::fill",1);
} }
template <class TYPE> 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 depth2 = data.size(3);
int ni = i0 == 0 ? n[0] : ng[0]; int ni = i0 == 0 ? n[0] : ng[0];
int nj = j0 == 0 ? n[1] : ng[1]; int nj = j0 == 0 ? n[1] : ng[1];
@ -319,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 k = 0; k < nk; k++) {
for (int j = 0; j < nj; j++) { for (int j = 0; j < nj; j++) {
for (int i = 0; i < ni; i++) { 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> 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 depth2 = data.size(3);
int ni = i0 == 0 ? n[0] : ng[0]; int ni = i0 == 0 ? n[0] : ng[0];
int nj = j0 == 0 ? n[1] : ng[1]; int nj = j0 == 0 ? n[1] : ng[1];
@ -339,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 k = 0; k < nk; k++) {
for (int j = 0; j < nj; j++) { for (int j = 0; j < nj; j++) {
for (int i = 0; i < ni; i++) { 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 * * Function to remove the ghost halo *
********************************************************/ ********************************************************/
template <class TYPE> template <class TYPE>
template <class TYPE1, class TYPE2> 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); //PROFILE_START("fillHalo::copy",1);
ASSERT((int)src.size(0) == n[0] || (int)src.size(0) == n[0] + 2 * ng[0]); 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]); ASSERT((int)dst.size(0) == n[0] || (int)dst.size(0) == n[0] + 2 * ng[0]);
@ -404,5 +414,4 @@ void fillHalo<TYPE>::copy( const Array<TYPE1>& src, Array<TYPE2>& dst )
//PROFILE_STOP("fillHalo::copy",1); //PROFILE_STOP("fillHalo::copy",1);
} }
#endif #endif

View File

@ -24,20 +24,17 @@
#include <string> #include <string>
#include <tuple> #include <tuple>
/******************************************************************** /********************************************************************
* Constructors/destructor * * Constructors/destructor *
********************************************************************/ ********************************************************************/
Database::Database() = default; Database::Database() = default;
Database::~Database() = default; Database::~Database() = default;
Database::Database( const Database& rhs ) : KeyData( rhs ) Database::Database(const Database &rhs) : KeyData(rhs) {
{
d_data.clear(); d_data.clear();
for (const auto &tmp : rhs.d_data) for (const auto &tmp : rhs.d_data)
putData(tmp.first, tmp.second->clone()); putData(tmp.first, tmp.second->clone());
} }
Database& Database::operator=( const Database& rhs ) Database &Database::operator=(const Database &rhs) {
{
if (this == &rhs) if (this == &rhs)
return *this; return *this;
d_data.clear(); d_data.clear();
@ -46,36 +43,30 @@ Database& Database::operator=( const Database& rhs )
return *this; return *this;
} }
Database::Database(Database &&rhs) { std::swap(d_data, rhs.d_data); } Database::Database(Database &&rhs) { std::swap(d_data, rhs.d_data); }
Database& Database::operator=( Database&& rhs ) Database &Database::operator=(Database &&rhs) {
{
if (this != &rhs) if (this != &rhs)
std::swap(d_data, rhs.d_data); std::swap(d_data, rhs.d_data);
return *this; return *this;
} }
/******************************************************************** /********************************************************************
* Clone the database * * Clone the database *
********************************************************************/ ********************************************************************/
std::shared_ptr<KeyData> Database::clone() const { return cloneDatabase(); } 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>(); auto db = std::make_shared<Database>();
for (const auto &tmp : d_data) for (const auto &tmp : d_data)
db->putData(tmp.first, tmp.second->clone()); db->putData(tmp.first, tmp.second->clone());
return db; return db;
} }
/******************************************************************** /********************************************************************
* Get the data object * * 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(); 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); auto it = d_data.find(key);
if (it == d_data.end()) { if (it == d_data.end()) {
char msg[1000]; char msg[1000];
@ -84,18 +75,15 @@ std::shared_ptr<KeyData> Database::getData( const std::string& key )
} }
return it->second; 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); 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 ptr = getData(key);
auto ptr2 = std::dynamic_pointer_cast<const Database>(ptr); auto ptr2 = std::dynamic_pointer_cast<const Database>(ptr);
return ptr2 != nullptr; 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<KeyData> ptr = getData(key);
std::shared_ptr<Database> ptr2 = std::dynamic_pointer_cast<Database>(ptr); std::shared_ptr<Database> ptr2 = std::dynamic_pointer_cast<Database>(ptr);
if (ptr2 == nullptr) { if (ptr2 == nullptr) {
@ -105,46 +93,37 @@ std::shared_ptr<Database> Database::getDatabase( const std::string& key )
} }
return ptr2; 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); 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; std::vector<std::string> keys;
keys.reserve(d_data.size()); keys.reserve(d_data.size());
for (const auto &it : d_data) for (const auto &it : d_data)
keys.push_back(it.first); keys.push_back(it.first);
return keys; 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); 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); d_data[key] = std::move(data);
} }
/******************************************************************** /********************************************************************
* Is the data of the given type * * Is the data of the given type *
********************************************************************/ ********************************************************************/
template<> template <> bool Database::isType<double>(const std::string &key) const {
bool Database::isType<double>( const std::string& key ) const
{
auto type = getData(key)->type(); auto type = getData(key)->type();
return type == "double"; return type == "double";
} }
template<> template <> bool Database::isType<float>(const std::string &key) const {
bool Database::isType<float>( const std::string& key ) const
{
auto type = getData(key)->type(); auto type = getData(key)->type();
return type == "double"; return type == "double";
} }
template<> template <> bool Database::isType<int>(const std::string &key) const {
bool Database::isType<int>( const std::string& key ) const
{
bool pass = true; bool pass = true;
auto type = getData(key)->type(); auto type = getData(key)->type();
if (type == "double") { if (type == "double") {
@ -156,27 +135,21 @@ bool Database::isType<int>( const std::string& key ) const
} }
return pass; return pass;
} }
template<> template <> bool Database::isType<std::string>(const std::string &key) const {
bool Database::isType<std::string>( const std::string& key ) const
{
auto type = getData(key)->type(); auto type = getData(key)->type();
return type == "string"; return type == "string";
} }
template<> template <> bool Database::isType<bool>(const std::string &key) const {
bool Database::isType<bool>( const std::string& key ) const
{
auto type = getData(key)->type(); auto type = getData(key)->type();
return type == "bool"; return type == "bool";
} }
/******************************************************************** /********************************************************************
* Get a vector * * Get a vector *
********************************************************************/ ********************************************************************/
template <> template <>
std::vector<std::string> Database::getVector<std::string>( std::vector<std::string>
const std::string& key, const Units& ) const Database::getVector<std::string>(const std::string &key, const Units &) const {
{
std::shared_ptr<const KeyData> ptr = getData(key); std::shared_ptr<const KeyData> ptr = getData(key);
if (std::dynamic_pointer_cast<const EmptyKeyData>(ptr)) if (std::dynamic_pointer_cast<const EmptyKeyData>(ptr))
return std::vector<std::string>(); return std::vector<std::string>();
@ -187,8 +160,8 @@ std::vector<std::string> Database::getVector<std::string>(
return ptr2->d_data; return ptr2->d_data;
} }
template <> 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); std::shared_ptr<const KeyData> ptr = getData(key);
if (std::dynamic_pointer_cast<const EmptyKeyData>(ptr)) if (std::dynamic_pointer_cast<const EmptyKeyData>(ptr))
return std::vector<bool>(); return std::vector<bool>();
@ -199,8 +172,8 @@ std::vector<bool> Database::getVector<bool>( const std::string& key, const Units
return ptr2->d_data; return ptr2->d_data;
} }
template <class TYPE> 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); std::shared_ptr<const KeyData> ptr = getData(key);
if (std::dynamic_pointer_cast<const EmptyKeyData>(ptr)) if (std::dynamic_pointer_cast<const EmptyKeyData>(ptr))
return std::vector<TYPE>(); return std::vector<TYPE>();
@ -227,29 +200,27 @@ std::vector<TYPE> Database::getVector( const std::string& key, const Units& unit
return data; return data;
} }
/******************************************************************** /********************************************************************
* Put a vector * * Put a vector *
********************************************************************/ ********************************************************************/
template <> template <>
void Database::putVector<std::string>( void Database::putVector<std::string>(const std::string &key,
const std::string& key, const std::vector<std::string>& data, const Units& ) const std::vector<std::string> &data,
{ const Units &) {
std::shared_ptr<KeyDataString> ptr(new KeyDataString()); std::shared_ptr<KeyDataString> ptr(new KeyDataString());
ptr->d_data = data; ptr->d_data = data;
d_data[key] = ptr; d_data[key] = ptr;
} }
template <> template <>
void Database::putVector<bool>( void Database::putVector<bool>(const std::string &key,
const std::string& key, const std::vector<bool>& data, const Units& ) const std::vector<bool> &data, const Units &) {
{
std::shared_ptr<KeyDataBool> ptr(new KeyDataBool()); std::shared_ptr<KeyDataBool> ptr(new KeyDataBool());
ptr->d_data = data; ptr->d_data = data;
d_data[key] = ptr; d_data[key] = ptr;
} }
template <class TYPE> 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()); std::shared_ptr<KeyDataDouble> ptr(new KeyDataDouble());
ptr->d_unit = unit; ptr->d_unit = unit;
ptr->d_data.resize(data.size()); ptr->d_data.resize(data.size());
@ -258,12 +229,10 @@ void Database::putVector( const std::string& key, const std::vector<TYPE>& data,
d_data[key] = ptr; d_data[key] = ptr;
} }
/******************************************************************** /********************************************************************
* Print the database * * 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) { for (const auto &it : d_data) {
os << indent << it.first; os << indent << it.first;
if (dynamic_cast<const Database *>(it.second.get())) { if (dynamic_cast<const Database *>(it.second.get())) {
@ -277,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; std::stringstream ss;
print(ss, indent); print(ss, indent);
return ss.str(); return ss.str();
} }
/******************************************************************** /********************************************************************
* Read input database file * * Read input database file *
********************************************************************/ ********************************************************************/
Database::Database( const std::string& filename ) Database::Database(const std::string &filename) {
{
// Read the input file into memory // Read the input file into memory
FILE *fid = fopen(filename.c_str(), "rb"); FILE *fid = fopen(filename.c_str(), "rb");
if (fid == nullptr) if (fid == nullptr)
@ -311,8 +277,7 @@ Database::Database( const std::string& filename )
// Free temporary memory // Free temporary memory
delete[] buffer; 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()); std::shared_ptr<Database> db(new Database());
auto *buffer = new char[data.size() + 4]; auto *buffer = new char[data.size() + 4];
memcpy(buffer, data.data(), data.size()); memcpy(buffer, data.data(), data.size());
@ -335,21 +300,20 @@ enum class token_type {
end_bracket, end_bracket,
end end
}; };
inline size_t length( token_type type ) inline size_t length(token_type type) {
{
size_t len = 0; size_t len = 0;
if ( type == token_type::newline || type == token_type::quote || type == token_type::equal || if (type == token_type::newline || type == token_type::quote ||
type == token_type::bracket || type == token_type::end_bracket || type == token_type::equal || type == token_type::bracket ||
type == token_type::end ) { type == token_type::end_bracket || type == token_type::end) {
len = 1; 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) { type == token_type::block_stop) {
len = 2; len = 2;
} }
return len; 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; size_t i = 0;
while (true) { while (true) {
if (buffer[i] == '\n' || buffer[i] == '\r') { if (buffer[i] == '\n' || buffer[i] == '\r') {
@ -363,23 +327,26 @@ inline std::tuple<size_t, token_type> find_next_token( const char* buffer )
} else if (buffer[i] == '{') { } else if (buffer[i] == '{') {
return std::pair<size_t, token_type>(i + 1, token_type::bracket); return std::pair<size_t, token_type>(i + 1, token_type::bracket);
} else if (buffer[i] == '}') { } 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] == '/') { } else if (buffer[i] == '/') {
if (buffer[i + 1] == '/') { 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] == '*') { } 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] == '*') { } else if (buffer[i] == '*') {
if (buffer[i + 1] == '/') 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++; i++;
} }
return std::pair<size_t, token_type>(0, token_type::end); 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; size_t i1 = 0xFFFFFFF, i2 = 0;
for (size_t i = 0; i < str.size(); i++) { for (size_t i = 0; i < str.size(); i++) {
if (str[i] != ' ') { if (str[i] != ' ') {
@ -389,12 +356,11 @@ inline std::string deblank( const std::string& str )
} }
return i1 <= i2 ? str.substr(i1, i2 - i1 + 1) : std::string(); 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); auto tmp = find_next_token(buffer);
const token_type end_comment = ( std::get<1>( tmp ) == token_type::line_comment ) ? const token_type end_comment =
token_type::newline : (std::get<1>(tmp) == token_type::line_comment) ? token_type::newline
token_type::block_stop; : token_type::block_stop;
size_t pos = 0; size_t pos = 0;
while (std::get<1>(tmp) != end_comment) { while (std::get<1>(tmp) != end_comment) {
if (std::get<1>(tmp) == token_type::end) if (std::get<1>(tmp) == token_type::end)
@ -405,15 +371,13 @@ size_t skip_comment( const char* buffer )
pos += std::get<0>(tmp); pos += std::get<0>(tmp);
return pos; return pos;
} }
inline std::string lower( const std::string& str ) inline std::string lower(const std::string &str) {
{
std::string tmp(str); std::string tmp(str);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
return tmp; return tmp;
} }
static std::tuple<size_t, std::shared_ptr<KeyData>> read_value( static std::tuple<size_t, std::shared_ptr<KeyData>>
const char* buffer, const std::string& key ) read_value(const char *buffer, const std::string &key) {
{
// Get the value as a std::string // Get the value as a std::string
size_t pos = 0; size_t pos = 0;
token_type type = token_type::end; token_type type = token_type::end;
@ -429,7 +393,8 @@ static std::tuple<size_t, std::shared_ptr<KeyData>> read_value(
std::tie(i, type) = find_next_token(&buffer[pos]); std::tie(i, type) = find_next_token(&buffer[pos]);
pos += i; 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); len = pos - length(type);
pos += skip_comment(&buffer[pos - length(type)]) - length(type); pos += skip_comment(&buffer[pos - length(type)]) - length(type);
break; break;
@ -462,7 +427,8 @@ static std::tuple<size_t, std::shared_ptr<KeyData>> read_value(
data2->d_data.resize(values.size()); data2->d_data.resize(values.size());
for (size_t i = 0; i < values.size(); i++) { for (size_t i = 0; i < values.size(); i++) {
ASSERT(values[i].size() >= 2); 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); data2->d_data[i] = values[i].substr(1, values[i].size() - 2);
} }
} else if (lower(value) == "true" || lower(value) == "false") { } else if (lower(value) == "true" || lower(value) == "false") {
@ -490,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); 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; size_t pos = 0;
while (true) { while (true) {
size_t i; size_t i;
token_type type; token_type type;
std::tie(i, type) = find_next_token(&buffer[pos]); std::tie(i, type) = find_next_token(&buffer[pos]);
const std::string key = const std::string key = deblank(
deblank( std::string( &buffer[pos], std::max<int>( i - length( type ), 1 ) - 1 ) ); std::string(&buffer[pos], std::max<int>(i - length(type), 1) - 1));
if ( type == token_type::line_comment || type == token_type::block_start ) { if (type == token_type::line_comment ||
type == token_type::block_start) {
// Comment // Comment
INSIST(key.empty(), "Key should be empty: " + key); INSIST(key.empty(), "Key should be empty: " + key);
pos += skip_comment(&buffer[pos]); pos += skip_comment(&buffer[pos]);
@ -533,12 +499,10 @@ size_t Database::loadDatabase( const char* buffer, Database& db )
return pos; return pos;
} }
/******************************************************************** /********************************************************************
* Data type helper functions * * 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; os << indent;
for (size_t i = 0; i < d_data.size(); i++) { for (size_t i = 0; i < d_data.size(); i++) {
if (i > 0) if (i > 0)
@ -557,19 +521,17 @@ void KeyDataDouble::print( std::ostream& os, const std::string& indent ) const
os << " " << d_unit.str(); os << " " << d_unit.str();
os << std::endl; 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); std::string tmp = deblank(str);
size_t index = tmp.find(" "); size_t index = tmp.find(" ");
if (index != std::string::npos) { if (index != std::string::npos) {
return std::make_tuple( return std::make_tuple(readValue(tmp.substr(0, index)),
readValue( tmp.substr( 0, index ) ), Units( tmp.substr( index + 1 ) ) ); Units(tmp.substr(index + 1)));
} else { } else {
return std::make_tuple(readValue(tmp), Units()); 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); const std::string tmp = lower(str);
double data = 0; double data = 0;
if (tmp == "inf" || tmp == "infinity") { if (tmp == "inf" || tmp == "infinity") {
@ -589,24 +551,33 @@ double KeyDataDouble::readValue( const std::string& str )
return data; return data;
} }
/******************************************************************** /********************************************************************
* Instantiations * * Instantiations *
********************************************************************/ ********************************************************************/
template std::vector<char> Database::getVector<char>( const std::string&, const Units& ) const; template std::vector<char> Database::getVector<char>(const std::string &,
template std::vector<int> Database::getVector<int>( const std::string&, const Units& ) const; const Units &) const;
template std::vector<size_t> Database::getVector<size_t>( const std::string&, const Units& ) const; template std::vector<int> Database::getVector<int>(const std::string &,
template std::vector<float> Database::getVector<float>( const std::string&, const Units& ) const; const Units &) const;
template std::vector<double> Database::getVector<double>( const std::string&, const Units& ) const; template std::vector<size_t> Database::getVector<size_t>(const std::string &,
template void Database::putVector<char>( const Units &) const;
const std::string&, const std::vector<char>&, const Units& ); template std::vector<float> Database::getVector<float>(const std::string &,
template void Database::putVector<int>( const std::string&, const std::vector<int>&, const Units& ); const Units &) const;
template void Database::putVector<size_t>( template std::vector<double> Database::getVector<double>(const std::string &,
const std::string&, const std::vector<size_t>&, const Units& ); const Units &) const;
template void Database::putVector<float>( template void Database::putVector<char>(const std::string &,
const std::string&, const std::vector<float>&, const Units& ); const std::vector<char> &,
template void Database::putVector<double>( const Units &);
const std::string&, const std::vector<double>&, 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<int>(const std::string &) const;
template bool Database::isType<float>(const std::string &) const; template bool Database::isType<float>(const std::string &) const;
template bool Database::isType<double>(const std::string &) const; template bool Database::isType<double>(const std::string &) const;

View File

@ -26,17 +26,13 @@
#include "common/Units.h" #include "common/Units.h"
inline bool exists(const std::string &filename) {
inline bool exists( const std::string& filename )
{
std::ifstream domain(filename); std::ifstream domain(filename);
return domain.good(); return domain.good();
} }
//! Base class to hold data of a given type //! Base class to hold data of a given type
class KeyData class KeyData {
{
protected: protected:
//! Empty constructor //! Empty constructor
KeyData() {} KeyData() {}
@ -47,7 +43,8 @@ public:
//! Copy the data //! Copy the data
virtual std::shared_ptr<KeyData> clone() const = 0; virtual std::shared_ptr<KeyData> clone() const = 0;
//! Print the data to a stream //! 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 //! Return the native data type
virtual std::string type() const = 0; virtual std::string type() const = 0;
@ -56,10 +53,8 @@ protected:
KeyData &operator=(const KeyData &); KeyData &operator=(const KeyData &);
}; };
//! Class to a database //! Class to a database
class Database : public KeyData class Database : public KeyData {
{
public: public:
//! Empty constructor //! Empty constructor
Database(); Database();
@ -97,7 +92,6 @@ public:
//! Copy the data //! Copy the data
std::shared_ptr<Database> cloneDatabase() const; std::shared_ptr<Database> cloneDatabase() const;
/** /**
* Return true if the specified key exists in the database and false * Return true if the specified key exists in the database and false
* otherwise. * otherwise.
@ -105,17 +99,14 @@ public:
*/ */
bool keyExists(const std::string &key) const; bool keyExists(const std::string &key) const;
/** /**
* Return all keys in the database. * Return all keys in the database.
*/ */
std::vector<std::string> getAllKeys() const; std::vector<std::string> getAllKeys() const;
//! Return the number of entries in the database //! Return the number of entries in the database
size_t size() const { return d_data.size(); } size_t size() const { return d_data.size(); }
/** /**
* Get the scalar entry from the database with the specified key * Get the scalar entry from the database with the specified key
* name. If the specified key does not exist in the database or * name. If the specified key does not exist in the database or
@ -126,13 +117,13 @@ public:
* @param[in] unit Desired units * @param[in] unit Desired units
*/ */
template <class TYPE> 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 /// @copydoc Database::getScalar(const std::string&,const Units&) const
template <class TYPE> 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 * Get the scalar entry from the database with the specified key
@ -144,15 +135,13 @@ public:
* @param[in] unit Desired units * @param[in] unit Desired units
*/ */
template <class TYPE> template <class TYPE>
inline TYPE getWithDefault( inline TYPE getWithDefault(const std::string &key, const TYPE &value,
const std::string& key, const TYPE& value, const Units& unit = Units() ) const; const Units &unit = Units()) const;
/// @copydoc Database::getWithDefault(const std::string&,const TYPE&,const Units&) const /// @copydoc Database::getWithDefault(const std::string&,const TYPE&,const Units&) const
template <class TYPE> template <class TYPE>
inline TYPE getWithDefault( inline TYPE getWithDefault(const std::string &key, const TYPE &value,
const std::string& key, const TYPE& value, const std::string& unit ) const; const std::string &unit) const;
/** /**
* Put the scalar entry into the database with the specified key name. * Put the scalar entry into the database with the specified key name.
@ -161,8 +150,8 @@ public:
* @param unit Desired units * @param unit Desired units
*/ */
template <class TYPE> 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. * Put the scalar entry into the database with the specified key name.
@ -171,8 +160,8 @@ public:
* @param unit Desired units * @param unit Desired units
*/ */
template <class TYPE> 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 * Get the vector entries from the database with the specified key
@ -184,13 +173,13 @@ public:
* @param unit Desired units * @param unit Desired units
*/ */
template <class TYPE> 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 /// @copydoc Database::getVector(const std::string&,const Units&) const
template <class TYPE> 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 * Put the vector entries into the database with the specified key
@ -203,15 +192,13 @@ public:
* @param unit Desired units * @param unit Desired units
*/ */
template <class TYPE> template <class TYPE>
void putVector( void putVector(const std::string &key, const std::vector<TYPE> &data,
const std::string& key, const std::vector<TYPE>& data, const Units& unit = Units() ); const Units &unit = Units());
/// @copydoc Database::putVector(const std::string&,const std::vector<TYPE>&,const Units&) /// @copydoc Database::putVector(const std::string&,const std::vector<TYPE>&,const Units&)
template <class TYPE> template <class TYPE>
inline void putVector( inline void putVector(const std::string &key, const std::vector<TYPE> &data,
const std::string& key, const std::vector<TYPE>& data, const std::string& unit ); const std::string &unit);
/** /**
* Get the data for a key in the database. If the specified key * Get the data for a key in the database. If the specified key
@ -231,7 +218,6 @@ public:
*/ */
std::shared_ptr<const KeyData> getData(const std::string &key) const; std::shared_ptr<const KeyData> getData(const std::string &key) const;
/** /**
* Put the data for a key in the database. * Put the data for a key in the database.
* *
@ -240,15 +226,11 @@ public:
*/ */
void putData(const std::string &key, std::shared_ptr<KeyData> data); void putData(const std::string &key, std::shared_ptr<KeyData> data);
// Check if the key is a database object // Check if the key is a database object
bool isDatabase(const std::string &key) const; bool isDatabase(const std::string &key) const;
// Check if the entry can be stored as the given type // Check if the entry can be stored as the given type
template<class TYPE> template <class TYPE> bool isType(const std::string &key) const;
bool isType( const std::string& key ) const;
/** /**
* Get the database for a key in the database. If the specified key * Get the database for a key in the database. If the specified key
@ -268,7 +250,6 @@ public:
*/ */
std::shared_ptr<const Database> getDatabase(const std::string &key) const; std::shared_ptr<const Database> getDatabase(const std::string &key) const;
/** /**
* Get the database for a key in the database. If the specified key * Get the database for a key in the database. If the specified key
* does not exist in the database an error message is printed and * does not exist in the database an error message is printed and
@ -279,26 +260,23 @@ public:
*/ */
void putDatabase(const std::string &key, std::shared_ptr<Database> db); void putDatabase(const std::string &key, std::shared_ptr<Database> db);
/** /**
* Print the data to a stream * Print the data to a stream
* @param os Output stream * @param os Output stream
* @param indent Indenting to use before each line * @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 //! Print the type
virtual std::string type() const override { return "database"; } virtual std::string type() const override { return "database"; }
/** /**
* Print the data to a string * Print the data to a string
* @return Output string * @return Output string
*/ */
std::string print(const std::string &indent = "") const; std::string print(const std::string &indent = "") const;
protected: protected:
std::map<std::string, std::shared_ptr<KeyData>> d_data; std::map<std::string, std::shared_ptr<KeyData>> d_data;
@ -306,7 +284,6 @@ protected:
static size_t loadDatabase(const char *buffer, Database &db); static size_t loadDatabase(const char *buffer, Database &db);
}; };
#include "common/Database.hpp" #include "common/Database.hpp"
#endif #endif

View File

@ -38,39 +38,33 @@
#include <tuple> #include <tuple>
/******************************************************************** /********************************************************************
* Basic classes for primative data types * * Basic classes for primative data types *
********************************************************************/ ********************************************************************/
class EmptyKeyData : public KeyData class EmptyKeyData : public KeyData {
{
public: public:
EmptyKeyData() {} EmptyKeyData() {}
virtual ~EmptyKeyData() {} virtual ~EmptyKeyData() {}
virtual std::shared_ptr<KeyData> clone() const override virtual std::shared_ptr<KeyData> clone() const override {
{
return std::make_shared<EmptyKeyData>(); 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; os << std::endl;
} }
virtual std::string type() const override { return ""; } virtual std::string type() const override { return ""; }
}; };
class KeyDataDouble : public KeyData class KeyDataDouble : public KeyData {
{
public: public:
KeyDataDouble() {} KeyDataDouble() {}
explicit KeyDataDouble(const std::vector<double> &data, const Units &unit) 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 ~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); 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"; } virtual std::string type() const override { return "double"; }
static std::tuple<double, Units> read(const std::string &); static std::tuple<double, Units> read(const std::string &);
@ -80,18 +74,16 @@ public:
std::vector<double> d_data; std::vector<double> d_data;
Units d_unit; Units d_unit;
}; };
class KeyDataBool : public KeyData class KeyDataBool : public KeyData {
{
public: public:
KeyDataBool() {} KeyDataBool() {}
explicit KeyDataBool(const std::vector<bool> &data) : d_data(data) {} explicit KeyDataBool(const std::vector<bool> &data) : d_data(data) {}
virtual ~KeyDataBool() {} 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); 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; os << indent;
for (size_t i = 0; i < d_data.size(); i++) { for (size_t i = 0; i < d_data.size(); i++) {
if (i > 0) { if (i > 0) {
@ -108,18 +100,17 @@ public:
virtual std::string type() const override { return "bool"; } virtual std::string type() const override { return "bool"; }
std::vector<bool> d_data; std::vector<bool> d_data;
}; };
class KeyDataString : public KeyData class KeyDataString : public KeyData {
{
public: public:
KeyDataString() {} 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 ~KeyDataString() {}
virtual std::shared_ptr<KeyData> clone() const override virtual std::shared_ptr<KeyData> clone() const override {
{
return std::make_shared<KeyDataString>(d_data); 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; os << indent;
for (size_t i = 0; i < d_data.size(); i++) { for (size_t i = 0; i < d_data.size(); i++) {
if (i > 0) { if (i > 0) {
@ -133,30 +124,27 @@ public:
std::vector<std::string> d_data; std::vector<std::string> d_data;
}; };
/******************************************************************** /********************************************************************
* Get a vector * * Get a vector *
********************************************************************/ ********************************************************************/
template <class TYPE> template <class TYPE>
inline std::vector<TYPE> Database::getVector( inline std::vector<TYPE> Database::getVector(const std::string &key,
const std::string& key, const std::string& unit ) const const std::string &unit) const {
{
return getVector<TYPE>(key, Units(unit)); return getVector<TYPE>(key, Units(unit));
} }
template <class TYPE> template <class TYPE>
inline void Database::putVector( inline void Database::putVector(const std::string &key,
const std::string& key, const std::vector<TYPE>& data, const std::string& unit ) const std::vector<TYPE> &data,
{ const std::string &unit) {
putVector<TYPE>(key, data, Units(unit)); putVector<TYPE>(key, data, Units(unit));
} }
/******************************************************************** /********************************************************************
* Get a scalar * * Get a scalar *
********************************************************************/ ********************************************************************/
template <class TYPE> 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); const std::vector<TYPE> &data = getVector<TYPE>(key, unit);
if (data.size() != 1) { if (data.size() != 1) {
char msg[1000]; char msg[1000];
@ -166,40 +154,36 @@ inline TYPE Database::getScalar( const std::string& key, const Units& unit ) con
return data[0]; return data[0];
} }
template <class TYPE> template <class TYPE>
inline TYPE Database::getWithDefault( inline TYPE Database::getWithDefault(const std::string &key, const TYPE &value,
const std::string& key, const TYPE& value, const Units& unit ) const const Units &unit) const {
{
if (!keyExists(key)) if (!keyExists(key))
return value; return value;
return getScalar<TYPE>(key, unit); return getScalar<TYPE>(key, unit);
} }
template <class TYPE> 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); putVector<TYPE>(key, std::vector<TYPE>(1, data), unit);
} }
template <class TYPE> 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)); return getScalar<TYPE>(key, Units(unit));
} }
template <class TYPE> template <class TYPE>
inline TYPE Database::getWithDefault( inline TYPE Database::getWithDefault(const std::string &key, const TYPE &value,
const std::string& key, const TYPE& value, const std::string& unit ) const const std::string &unit) const {
{
return getWithDefault<TYPE>(key, value, Units(unit)); return getWithDefault<TYPE>(key, value, Units(unit));
} }
template <class TYPE> 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)); putScalar<TYPE>(key, data, Units(unit));
} }
template <class TYPE> template <class TYPE>
inline void putVector( inline void putVector(const std::string &key, const std::vector<TYPE> &data,
const std::string& key, const std::vector<TYPE>& data, const std::string& unit ) const std::string &unit) {
{
putVector<TYPE>(key, data, Units(unit)); putVector<TYPE>(key, data, Units(unit));
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,6 @@
* \brief Parallel Domain data structures and helper functions * \brief Parallel Domain data structures and helper functions
*/ */
/** /**
* \class Box * \class Box
* *
@ -118,9 +117,7 @@ public:
*/ */
inline const std::vector<Patch> &getAllPatch() const { return d_patches; } inline const std::vector<Patch> &getAllPatch() const { return d_patches; }
private: private:
/** /**
* \brief initialize from database * \brief initialize from database
*/ */
@ -131,9 +128,7 @@ private:
Patch *d_localPatch; Patch *d_localPatch;
std::vector<Patch> d_patches; std::vector<Patch> d_patches;
public: // Public variables (need to create accessors instead) public: // Public variables (need to create accessors instead)
std::shared_ptr<Database> database; std::shared_ptr<Database> database;
double Lx, Ly, Lz, Volume, voxel_length; double Lx, Ly, Lz, Volume, voxel_length;
int Nx, Ny, Nz, N; int Nx, Ny, Nz, N;
@ -186,10 +181,18 @@ public: // Public variables (need to create accessors instead)
// Get the actual D3Q19 communication counts (based on location of solid phase) // Get the actual D3Q19 communication counts (based on location of solid phase)
// Discrete velocity set symmetry implies the sendcount = recvcount // Discrete velocity set symmetry implies the sendcount = recvcount
//...................................................................................... //......................................................................................
inline int recvCount( const char* dir ) const { return getRecvList( dir ).size(); } inline int recvCount(const char *dir) const {
inline int sendCount( const char* dir ) const { return getSendList( dir ).size(); } return getRecvList(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 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 // Solid indicator function
@ -234,7 +237,8 @@ public: // Public variables (need to create accessors instead)
* @param Datatype - data type to use * @param Datatype - data type to use
* @param UserData - Array to store the values that are read * @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 * \brief Aggregate labels from all MPI processes and write to a file
@ -249,7 +253,6 @@ public: // Public variables (need to create accessors instead)
void AggregateLabels(const std::string &filename, DoubleArray &UserData); void AggregateLabels(const std::string &filename, DoubleArray &UserData);
private: private:
/** /**
* \brief Pack halo data for 8-bit integer * \brief Pack halo data for 8-bit integer
* @param list - list of values in the halo * @param list - list of values in the halo
@ -271,25 +274,28 @@ private:
//...................................................................................... //......................................................................................
MPI_Request req1[18], req2[18]; 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_x, sendList_y, sendList_z, sendList_X, sendList_Y,
std::vector<int> sendList_xy, sendList_yz, sendList_xz, sendList_Xy, sendList_Yz, sendList_xZ; 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_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_x, recvList_y, recvList_z, recvList_X, recvList_Y,
std::vector<int> recvList_xy, recvList_yz, recvList_xz, recvList_Xy, recvList_Yz, recvList_xZ; 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_xY, recvList_yZ, recvList_Xz, recvList_XY,
recvList_YZ, recvList_XZ;
//...................................................................................... //......................................................................................
const std::vector<int> &getRecvList(const char *dir) const; const std::vector<int> &getRecvList(const char *dir) const;
const std::vector<int> &getSendList(const char *dir) const; const std::vector<int> &getSendList(const char *dir) const;
}; };
template <class TYPE> class PatchData; template <class TYPE> class PatchData;
enum class DataLocation { CPU, DEVICE }; enum class DataLocation { CPU, DEVICE };
/** /**
* \class Patch * \class Patch
* *
@ -298,7 +304,6 @@ enum class DataLocation { CPU, DEVICE };
*/ */
class Patch { class Patch {
public: public:
//! Empty constructor //! Empty constructor
Patch() = delete; Patch() = delete;
@ -313,21 +318,18 @@ public:
//! Create patch data //! Create patch data
template <class TYPE> template <class TYPE>
std::shared_ptr<PatchData<TYPE>> createPatchData( DataLocation location ) const; std::shared_ptr<PatchData<TYPE>>
createPatchData(DataLocation location) const;
private: private:
Box d_box; Box d_box;
int d_owner; int d_owner;
Domain *d_domain; Domain *d_domain;
}; };
// Class to hold data on a patch // Class to hold data on a patch
template<class TYPE> template <class TYPE> class PatchData {
class PatchData {
public: public:
//! Get the raw data pointer //! Get the raw data pointer
TYPE *data() { return d_data; } TYPE *data() { return d_data; }
@ -354,10 +356,10 @@ private:
const Patch *d_patch; const Patch *d_patch;
TYPE *d_data; TYPE *d_data;
TYPE *d_gcw; 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); void ReadCheckpoint(char *FILENAME, double *cDen, double *cfq, size_t Np);

View File

@ -1,6 +1,5 @@
#include "FunctionTable.hpp" #include "FunctionTable.hpp"
/******************************************************** /********************************************************
* Random number generation * * Random number generation *
********************************************************/ ********************************************************/
@ -94,54 +93,35 @@ template<> long double genRand<long double>()
* axpy * * axpy *
********************************************************/ ********************************************************/
template <> 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"); ERROR("Not finished");
} }
template <> 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"); ERROR("Not finished");
} }
/******************************************************** /********************************************************
* Multiply two arrays * * Multiply two arrays *
********************************************************/ ********************************************************/
template <> template <>
void call_gemv<double>( void call_gemv<double>(size_t M, size_t N, double alpha, double beta,
size_t M, size_t N, double alpha, double beta, const double *A, const double *x, double *y ) const double *A, const double *x, double *y) {
{
ERROR("Not finished"); ERROR("Not finished");
} }
template <> template <>
void call_gemv<float>( void call_gemv<float>(size_t M, size_t N, float alpha, float beta,
size_t M, size_t N, float alpha, float beta, const float *A, const float *x, float *y ) const float *A, const float *x, float *y) {
{
ERROR("Not finished"); ERROR("Not finished");
} }
template <> template <>
void call_gemm<double>( size_t M, void call_gemm<double>(size_t M, size_t N, size_t K, double alpha, double beta,
size_t N, const double *A, const double *B, double *C) {
size_t K,
double alpha,
double beta,
const double *A,
const double *B,
double *C )
{
ERROR("Not finished"); ERROR("Not finished");
} }
template <> template <>
void call_gemm<float>( size_t M, void call_gemm<float>(size_t M, size_t N, size_t K, float alpha, float beta,
size_t N, const float *A, const float *B, float *C) {
size_t K,
float alpha,
float beta,
const float *A,
const float *B,
float *C )
{
ERROR("Not finished"); ERROR("Not finished");
} }

View File

@ -17,28 +17,23 @@
#ifndef included_FunctionTable #ifndef included_FunctionTable
#define included_FunctionTable #define included_FunctionTable
#include "common/ArraySize.h" #include "common/ArraySize.h"
#include <functional> #include <functional>
/*! /*!
* Class FunctionTable is a serial function table class that defines * Class FunctionTable is a serial function table class that defines
* a series of operations that can be performed on the Array class. * a series of operations that can be performed on the Array class.
* Users can impliment additional versions of the function table that match * Users can impliment additional versions of the function table that match
* the interface to change the behavior of the array class. * the interface to change the behavior of the array class.
*/ */
class FunctionTable final class FunctionTable final {
{
public: public:
/*! /*!
* Initialize the array with random values * Initialize the array with random values
* @param[in] x The array to operate on * @param[in] x The array to operate on
*/ */
template<class TYPE, class FUN> template <class TYPE, class FUN> static void rand(Array<TYPE, FUN> &x);
static void rand( Array<TYPE, FUN> &x );
/*! /*!
* Perform a reduce operator y = f(x) * Perform a reduce operator y = f(x)
@ -50,7 +45,8 @@ public:
* @return The reduction * @return The reduction
*/ */
template <class TYPE, class FUN, typename LAMBDA> 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) * Perform a reduce operator z = f(x,y)
@ -63,8 +59,7 @@ public:
* @return The reduction * @return The reduction
*/ */
template <class TYPE, class FUN, typename LAMBDA> template <class TYPE, class FUN, typename LAMBDA>
static inline TYPE reduce( LAMBDA &op, static inline TYPE reduce(LAMBDA &op, const Array<TYPE, FUN> &A,
const Array<TYPE, FUN> &A,
const Array<TYPE, FUN> &B, const Array<TYPE, FUN> &B,
const TYPE &initialValue); const TYPE &initialValue);
@ -76,7 +71,8 @@ public:
* @param[out] y The output array * @param[out] y The output array
*/ */
template <class TYPE, class FUN, typename LAMBDA> 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) * Perform a element-wise operation z = f(x,y)
@ -87,8 +83,7 @@ public:
* @param[out] z The output array * @param[out] z The output array
*/ */
template <class TYPE, class FUN, typename LAMBDA> template <class TYPE, class FUN, typename LAMBDA>
static inline void transform( LAMBDA &fun, static inline void transform(LAMBDA &fun, const Array<TYPE, FUN> &x,
const Array<TYPE, FUN> &x,
const Array<TYPE, FUN> &y, const Array<TYPE, FUN> &y,
Array<TYPE, FUN> &z); Array<TYPE, FUN> &z);
@ -99,8 +94,8 @@ public:
* @param[out] c The output array * @param[out] c The output array
*/ */
template <class TYPE, class FUN> template <class TYPE, class FUN>
static void static void multiply(const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b,
multiply( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, Array<TYPE, FUN> &c ); Array<TYPE, FUN> &c);
/*! /*!
* Perform dgemv/dgemm equavalent operation ( C = alpha*A*B + beta*C ) * Perform dgemv/dgemm equavalent operation ( C = alpha*A*B + beta*C )
@ -111,10 +106,8 @@ public:
* @param[in,out] C The output array C * @param[in,out] C The output array C
*/ */
template <class TYPE, class FUN> template <class TYPE, class FUN>
static void gemm( const TYPE alpha, static void gemm(const TYPE alpha, const Array<TYPE, FUN> &A,
const Array<TYPE, FUN> &A, const Array<TYPE, FUN> &B, const TYPE beta,
const Array<TYPE, FUN> &B,
const TYPE beta,
Array<TYPE, FUN> &C); Array<TYPE, FUN> &C);
/*! /*!
@ -124,7 +117,8 @@ public:
* @param[in,out] y The output array y * @param[in,out] y The output array y
*/ */
template <class TYPE, class FUN> 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 * Check if two arrays are approximately equal
@ -133,24 +127,15 @@ public:
* @param[in] tol The tolerance * @param[in] tol The tolerance
*/ */
template <class TYPE, class FUN> 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> template <class TYPE>
static inline void gemmWrapper( char TRANSA, static inline void gemmWrapper(char TRANSA, char TRANSB, int M, int N,
char TRANSB, int K, TYPE alpha, const TYPE *A, int LDA,
int M, const TYPE *B, int LDB, TYPE beta, TYPE *C,
int N,
int K,
TYPE alpha,
const TYPE *A,
int LDA,
const TYPE *B,
int LDB,
TYPE beta,
TYPE *C,
int LDC); int LDC);
/* Specialized Functions */ /* Specialized Functions */
/*! /*!
@ -159,7 +144,8 @@ public:
* @param[out] B The output array * @param[out] B The output array
*/ */
template <class TYPE, class FUN, class ALLOC> 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| * Perform a element-wise operation B = |A|
@ -167,7 +153,8 @@ public:
* @param[out] B The output array * @param[out] B The output array
*/ */
template <class TYPE, class FUN, class ALLOC> 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) * Perform a element-wise operation B = tanh(A)
@ -175,7 +162,8 @@ public:
* @param[out] B The output array * @param[out] B The output array
*/ */
template <class TYPE, class FUN, class ALLOC> 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) ) * Perform a element-wise operation B = max(-1 , min(1 , A) )
@ -183,7 +171,8 @@ public:
* @param[out] B The output array * @param[out] B The output array
*/ */
template <class TYPE, class FUN, class ALLOC> 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)) * Perform a element-wise operation B = 1 / (1 + exp(-A))
@ -191,7 +180,8 @@ public:
* @param[out] B The output array * @param[out] B The output array
*/ */
template <class TYPE, class FUN, class ALLOC> 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) * Perform a element-wise operation B = log(exp(A) + 1)
@ -199,7 +189,8 @@ public:
* @param[out] B The output array * @param[out] B The output array
*/ */
template <class TYPE, class FUN, class ALLOC> 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 * Sum the elements of the Array
@ -211,9 +202,7 @@ public:
private: private:
FunctionTable(); FunctionTable();
template<class T> template <class T> static inline void rand(size_t N, T *x);
static inline void rand( size_t N, T *x );
}; };
#endif #endif

View File

@ -41,7 +41,6 @@
#include <limits> #include <limits>
//#include <random> //#include <random>
/******************************************************** /********************************************************
* Random number initialization * * Random number initialization *
********************************************************/ ********************************************************/
@ -58,8 +57,8 @@ inline void FunctionTable::rand( Array<TYPE, FUN> &x )
* Reduction * * Reduction *
********************************************************/ ********************************************************/
template <class TYPE, class FUN, typename LAMBDA> 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) if (A.length() == 0)
return TYPE(); return TYPE();
const TYPE *x = A.data(); const TYPE *x = A.data();
@ -69,11 +68,9 @@ inline TYPE FunctionTable::reduce( LAMBDA &op, const Array<TYPE, FUN> &A, const
return y; return y;
} }
template <class TYPE, class FUN, typename LAMBDA> template <class TYPE, class FUN, typename LAMBDA>
inline TYPE FunctionTable::reduce( LAMBDA &op, inline TYPE FunctionTable::reduce(LAMBDA &op, const Array<TYPE, FUN> &A,
const Array<TYPE, FUN> &A,
const Array<TYPE, FUN> &B, const Array<TYPE, FUN> &B,
const TYPE &initialValue ) const TYPE &initialValue) {
{
ARRAY_ASSERT(A.length() == B.length()); ARRAY_ASSERT(A.length() == B.length());
if (A.length() == 0) if (A.length() == 0)
return TYPE(); return TYPE();
@ -85,24 +82,21 @@ inline TYPE FunctionTable::reduce( LAMBDA &op,
return z; return z;
} }
/******************************************************** /********************************************************
* Unary transformation * * Unary transformation *
********************************************************/ ********************************************************/
template <class TYPE, class FUN, typename LAMBDA> 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()); y.resize(x.size());
const size_t N = x.length(); const size_t N = x.length();
for (size_t i = 0; i < N; i++) for (size_t i = 0; i < N; i++)
y(i) = fun(x(i)); y(i) = fun(x(i));
} }
template <class TYPE, class FUN, typename LAMBDA> template <class TYPE, class FUN, typename LAMBDA>
inline void FunctionTable::transform( LAMBDA &fun, inline void FunctionTable::transform(LAMBDA &fun, const Array<TYPE, FUN> &x,
const Array<TYPE, FUN> &x,
const Array<TYPE, FUN> &y, const Array<TYPE, FUN> &y,
Array<TYPE, FUN> &z ) Array<TYPE, FUN> &z) {
{
if (x.size() != y.size()) if (x.size() != y.size())
throw std::logic_error("Sizes of x and y do not match"); throw std::logic_error("Sizes of x and y do not match");
z.resize(x.size()); z.resize(x.size());
@ -111,7 +105,6 @@ inline void FunctionTable::transform( LAMBDA &fun,
z(i) = fun(x(i), y(i)); z(i) = fun(x(i), y(i));
} }
/******************************************************** /********************************************************
* axpy * * axpy *
********************************************************/ ********************************************************/
@ -120,36 +113,36 @@ void call_axpy( size_t N, const TYPE alpha, const TYPE *x, TYPE *y );
template <> 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);
template <> 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> 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++) for (size_t i = 0; i < N; i++)
y[i] += alpha * x[i]; y[i] += alpha * x[i];
} }
template <class TYPE, class FUN> 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()) if (x.size() != y.size())
throw std::logic_error("Array sizes do not match"); throw std::logic_error("Array sizes do not match");
call_axpy(x.length(), alpha, x.data(), y.data()); call_axpy(x.length(), alpha, x.data(), y.data());
} }
/******************************************************** /********************************************************
* Multiply two arrays * * Multiply two arrays *
********************************************************/ ********************************************************/
template <class TYPE> 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 <> template <>
void call_gemv<double>( void call_gemv<double>(size_t M, size_t N, double alpha, double beta,
size_t M, size_t N, double alpha, double beta, const double *A, const double *x, double *y ); const double *A, const double *x, double *y);
template <> template <>
void call_gemv<float>( void call_gemv<float>(size_t M, size_t N, float alpha, float beta,
size_t M, size_t N, float alpha, float beta, const float *A, const float *x, float *y ); const float *A, const float *x, float *y);
template <class TYPE> 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++) for (size_t i = 0; i < M; i++)
y[i] = beta * y[i]; y[i] = beta * y[i];
for (size_t j = 0; j < N; j++) { for (size_t j = 0; j < N; j++) {
@ -158,30 +151,17 @@ void call_gemv( size_t M, size_t N, TYPE alpha, TYPE beta, const TYPE *A, const
} }
} }
template <class TYPE> template <class TYPE>
void call_gemm( void call_gemm(size_t M, size_t N, size_t K, TYPE alpha, TYPE beta,
size_t M, size_t N, size_t K, TYPE alpha, TYPE beta, const TYPE *A, const TYPE *B, TYPE *C ); const TYPE *A, const TYPE *B, TYPE *C);
template <> template <>
void call_gemm<double>( size_t M, void call_gemm<double>(size_t M, size_t N, size_t K, double alpha, double beta,
size_t N, const double *A, const double *B, double *C);
size_t K,
double alpha,
double beta,
const double *A,
const double *B,
double *C );
template <> template <>
void call_gemm<float>( size_t M, void call_gemm<float>(size_t M, size_t N, size_t K, float alpha, float beta,
size_t N, const float *A, const float *B, float *C);
size_t K,
float alpha,
float beta,
const float *A,
const float *B,
float *C );
template <class TYPE> template <class TYPE>
void call_gemm( void call_gemm(size_t M, size_t N, size_t K, TYPE alpha, TYPE beta,
size_t M, size_t N, size_t K, TYPE alpha, TYPE beta, const TYPE *A, const TYPE *B, TYPE *C ) const TYPE *A, const TYPE *B, TYPE *C) {
{
for (size_t i = 0; i < K * M; i++) for (size_t i = 0; i < K * M; i++)
C[i] = beta * C[i]; C[i] = beta * C[i];
for (size_t k = 0; k < K; k++) { for (size_t k = 0; k < K; k++) {
@ -192,50 +172,46 @@ void call_gemm(
} }
} }
template <class TYPE, class FUN> template <class TYPE, class FUN>
void FunctionTable::gemm( const TYPE alpha, void FunctionTable::gemm(const TYPE alpha, const Array<TYPE, FUN> &a,
const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, const TYPE beta,
const Array<TYPE, FUN> &b, Array<TYPE, FUN> &c) {
const TYPE beta,
Array<TYPE, FUN> &c )
{
if (a.size(1) != b.size(0)) if (a.size(1) != b.size(0))
throw std::logic_error("Inner dimensions must match"); throw std::logic_error("Inner dimensions must match");
if (a.ndim() == 2 && b.ndim() == 1) { 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) { } else if (a.ndim() <= 2 && b.ndim() <= 2) {
call_gemm<TYPE>( call_gemm<TYPE>(a.size(0), a.size(1), b.size(1), alpha, beta, a.data(),
a.size( 0 ), a.size( 1 ), b.size( 1 ), alpha, beta, a.data(), b.data(), c.data() ); b.data(), c.data());
} else { } else {
throw std::logic_error("Not finished yet"); throw std::logic_error("Not finished yet");
} }
} }
template <class TYPE, class FUN> template <class TYPE, class FUN>
void FunctionTable::multiply(const Array<TYPE, FUN> &a, void FunctionTable::multiply(const Array<TYPE, FUN> &a,
const Array<TYPE, FUN> &b, const Array<TYPE, FUN> &b, Array<TYPE, FUN> &c) {
Array<TYPE, FUN> &c )
{
if (a.size(1) != b.size(0)) if (a.size(1) != b.size(0))
throw std::logic_error("Inner dimensions must match"); throw std::logic_error("Inner dimensions must match");
if (a.ndim() == 2 && b.ndim() == 1) { if (a.ndim() == 2 && b.ndim() == 1) {
c.resize(a.size(0)); 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) { } else if (a.ndim() <= 2 && b.ndim() <= 2) {
c.resize(a.size(0), b.size(1)); c.resize(a.size(0), b.size(1));
call_gemm<TYPE>( call_gemm<TYPE>(a.size(0), a.size(1), b.size(1), 1, 0, a.data(),
a.size( 0 ), a.size( 1 ), b.size( 1 ), 1, 0, a.data(), b.data(), c.data() ); b.data(), c.data());
} else { } else {
throw std::logic_error("Not finished yet"); throw std::logic_error("Not finished yet");
} }
} }
/******************************************************** /********************************************************
* Check if two arrays are equal * * Check if two arrays are equal *
********************************************************/ ********************************************************/
template <class TYPE, class FUN> template <class TYPE, class FUN>
inline typename std::enable_if<std::is_integral<TYPE>::value, bool>::type 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; bool pass = true;
if (a.size() != b.size()) if (a.size() != b.size())
throw std::logic_error("Sizes of x and y do not match"); throw std::logic_error("Sizes of x and y do not match");
@ -245,8 +221,8 @@ FunctionTableCompare( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, TYPE
} }
template <class TYPE, class FUN> template <class TYPE, class FUN>
inline typename std::enable_if<std::is_floating_point<TYPE>::value, bool>::type 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; bool pass = true;
if (a.size() != b.size()) if (a.size() != b.size())
throw std::logic_error("Sizes of x and y do not match"); throw std::logic_error("Sizes of x and y do not match");
@ -255,32 +231,33 @@ FunctionTableCompare( const Array<TYPE, FUN> &a, const Array<TYPE, FUN> &b, TYPE
return pass; return pass;
} }
template <class TYPE, class FUN> 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); return FunctionTableCompare(a, b, tol);
} }
/******************************************************** /********************************************************
* Specialized Functions * * Specialized Functions *
********************************************************/ ********************************************************/
template <class TYPE, class FUN, class ALLOC> template <class TYPE, class FUN, class ALLOC>
void FunctionTable::transformReLU( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE, FUN, ALLOC> &B ) 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 ) ); }; const auto &fun = [](const TYPE &a) {
return std::max(a, static_cast<TYPE>(0));
};
transform(fun, A, B); transform(fun, A, B);
} }
template <class TYPE, class FUN, class ALLOC> 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()); B.resize(A.size());
const auto &fun = [](const TYPE &a) { return std::abs(a); }; const auto &fun = [](const TYPE &a) { return std::abs(a); };
transform(fun, A, B); transform(fun, A, B);
} }
template <class TYPE, class FUN, class ALLOC> 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()); B.resize(A.size());
const auto &fun = [](const TYPE &a) { return tanh(a); }; const auto &fun = [](const TYPE &a) { return tanh(a); };
transform(fun, A, B); transform(fun, A, B);
@ -288,18 +265,18 @@ void FunctionTable::transformTanh( const Array<TYPE, FUN, ALLOC> &A, Array<TYPE,
template <class TYPE, class FUN, class ALLOC> template <class TYPE, class FUN, class ALLOC>
void FunctionTable::transformHardTanh(const Array<TYPE, FUN, ALLOC> &A, void FunctionTable::transformHardTanh(const Array<TYPE, FUN, ALLOC> &A,
Array<TYPE, FUN, ALLOC> &B ) Array<TYPE, FUN, ALLOC> &B) {
{
B.resize(A.size()); B.resize(A.size());
const auto &fun = [](const TYPE &a) { 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); transform(fun, A, B);
} }
template <class TYPE, class FUN, class ALLOC> 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()); B.resize(A.size());
const auto &fun = [](const TYPE &a) { return 1.0 / (1.0 + exp(-a)); }; const auto &fun = [](const TYPE &a) { return 1.0 / (1.0 + exp(-a)); };
transform(fun, A, B); transform(fun, A, B);
@ -307,37 +284,24 @@ void FunctionTable::transformSigmoid( const Array<TYPE, FUN, ALLOC> &A, Array<TY
template <class TYPE, class FUN, class ALLOC> template <class TYPE, class FUN, class ALLOC>
void FunctionTable::transformSoftPlus(const Array<TYPE, FUN, ALLOC> &A, void FunctionTable::transformSoftPlus(const Array<TYPE, FUN, ALLOC> &A,
Array<TYPE, FUN, ALLOC> &B ) Array<TYPE, FUN, ALLOC> &B) {
{
B.resize(A.size()); B.resize(A.size());
const auto &fun = [](const TYPE &a) { return log1p(exp(a)); }; const auto &fun = [](const TYPE &a) { return log1p(exp(a)); };
transform(fun, A, B); transform(fun, A, B);
} }
template <class TYPE, class FUN, class ALLOC> 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; }; const auto &fun = [](const TYPE &a, const TYPE &b) { return a + b; };
return reduce(fun, A, (TYPE)0); return reduce(fun, A, (TYPE)0);
} }
template <class TYPE> template <class TYPE>
inline void FunctionTable::gemmWrapper( char TRANSA, inline void FunctionTable::gemmWrapper(char TRANSA, char TRANSB, int M, int N,
char TRANSB, int K, TYPE alpha, const TYPE *A,
int M, int LDA, const TYPE *B, int LDB,
int N, TYPE beta, TYPE *C, int LDC) {
int K,
TYPE alpha,
const TYPE *A,
int LDA,
const TYPE *B,
int LDB,
TYPE beta,
TYPE *C,
int LDC )
{
ERROR("Not finished"); ERROR("Not finished");
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,6 @@ redistribution is prohibited.
#ifndef included_LBPM_MPI #ifndef included_LBPM_MPI
#define included_LBPM_MPI #define included_LBPM_MPI
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <complex> #include <complex>
@ -31,7 +30,6 @@ redistribution is prohibited.
#include <string> #include <string>
#include <vector> #include <vector>
// Include mpi.h (or define MPI objects) // Include mpi.h (or define MPI objects)
// clang-format off // clang-format off
#ifdef USE_MPI #ifdef USE_MPI
@ -48,10 +46,8 @@ redistribution is prohibited.
#endif #endif
// clang-format on // clang-format on
namespace Utilities { namespace Utilities {
/** /**
* \class MPI * \class MPI
* *
@ -69,8 +65,7 @@ namespace Utilities {
* succeed provided that the size of the data type object is a fixed size on * 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. * all processors. sizeof(type) must be the same for all elements and processors.
*/ */
class MPI final class MPI final {
{
public: public:
enum class ThreadSupport : int { SINGLE, FUNNELED, SERIALIZED, MULTIPLE }; enum class ThreadSupport : int { SINGLE, FUNNELED, SERIALIZED, MULTIPLE };
@ -87,11 +82,9 @@ public: // Constructors
*/ */
MPI(); MPI();
//! Empty destructor //! Empty destructor
~MPI(); ~MPI();
/** /**
* \brief Constructor from existing MPI communicator * \brief Constructor from existing MPI communicator
* \details This constructor creates a new communicator from an 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); MPI(MPI_Comm comm, bool manage = false);
/** /**
* \brief Constructor from existing communicator * \brief Constructor from existing communicator
* \details This constructor creates a new communicator from an existing communicator. * \details This constructor creates a new communicator from an existing communicator.
@ -115,14 +107,12 @@ public: // Constructors
*/ */
MPI(const MPI &comm); MPI(const MPI &comm);
/*! /*!
* Move constructor * Move constructor
* @param rhs Communicator to copy * @param rhs Communicator to copy
*/ */
MPI(MPI &&rhs); MPI(MPI &&rhs);
/** /**
* \brief Assignment operator * \brief Assignment operator
* \details This operator overloads the assignment to correctly copy an communicator * \details This operator overloads the assignment to correctly copy an communicator
@ -130,21 +120,18 @@ public: // Constructors
*/ */
MPI &operator=(const MPI &comm); MPI &operator=(const MPI &comm);
/*! /*!
* Move assignment operator * Move assignment operator
* @param rhs Communicator to copy * @param rhs Communicator to copy
*/ */
MPI &operator=(MPI &&rhs); MPI &operator=(MPI &&rhs);
/** /**
* \brief Reset the object * \brief Reset the object
* \details This resets the object to the empty state without an MPI_Comm * \details This resets the object to the empty state without an MPI_Comm
*/ */
void reset(); void reset();
public: // Member functions public: // Member functions
/** /**
* \brief Get the node name * \brief Get the node name
@ -153,19 +140,15 @@ public: // Member functions
*/ */
static std::string getNodeName(); static std::string getNodeName();
//! Function to return the number of processors available //! Function to return the number of processors available
static int getNumberOfProcessors(); static int getNumberOfProcessors();
//! Function to return the affinity of the current process //! Function to return the affinity of the current process
static std::vector<int> getProcessAffinity(); static std::vector<int> getProcessAffinity();
//! Function to set the affinity of the current process //! Function to set the affinity of the current process
static void setProcessAffinity(const std::vector<int> &procs); static void setProcessAffinity(const std::vector<int> &procs);
/** /**
* \brief Load balance the processes within a node * \brief Load balance the processes within a node
* \details This function will redistribute the processes within a node using the * \details This function will redistribute the processes within a node using the
@ -189,22 +172,21 @@ public: // Member functions
* processors). * processors).
* *
*/ */
static void balanceProcesses( const MPI &comm = MPI( MPI_COMM_WORLD ), const int method = 1, static void
const std::vector<int> &procs = std::vector<int>(), const int N_min = 1, balanceProcesses(const MPI &comm = MPI(MPI_COMM_WORLD),
const int N_max = -1 ); 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 //! Query the level of thread support
static ThreadSupport queryThreadSupport(); static ThreadSupport queryThreadSupport();
/** /**
* \brief Generate a random number * \brief Generate a random number
* \details This generates a random number that is consistent across the comm * \details This generates a random number that is consistent across the comm
*/ */
size_t rand() const; size_t rand() const;
/** /**
* \brief Split an existing communicator * \brief Split an existing communicator
* \details This creates a new communicator by splitting 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; MPI split(int color, int key = -1) const;
/** /**
* \brief Split an existing communicator by node * \brief Split an existing communicator by node
* \details This creates a new communicator by splitting an existing communicator * \details This creates a new communicator by splitting an existing communicator
@ -242,7 +223,6 @@ public: // Member functions
*/ */
MPI splitByNode(int key = -1) const; MPI splitByNode(int key = -1) const;
/** /**
* \brief Duplicate an existing communicator * \brief Duplicate an existing communicator
* \details This creates a new communicator by duplicating an existing communicator. * \details This creates a new communicator by duplicating an existing communicator.
@ -253,7 +233,6 @@ public: // Member functions
*/ */
MPI dup() const; MPI dup() const;
/** /**
* \brief Create a communicator from the intersection of two communicators * \brief Create a communicator from the intersection of two communicators
* \details This creates a new communicator by intersecting two existing 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); static MPI intersect(const MPI &comm1, const MPI &comm2);
/** /**
* Check if the current communicator is NULL * Check if the current communicator is NULL
*/ */
bool isNull() const { return d_isNull; } bool isNull() const { return d_isNull; }
/** /**
* \brief Return the global ranks for the comm * \brief Return the global ranks for the comm
* \details This returns a vector which contains the global ranks for each * \details This returns a vector which contains the global ranks for each
@ -283,7 +260,6 @@ public: // Member functions
*/ */
std::vector<int> globalRanks() const; std::vector<int> globalRanks() const;
/** /**
* Get the current MPI communicator. * Get the current MPI communicator.
* Note: The underlying MPI_Comm object may be free'd by the object when it is no * 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; } const MPI_Comm &getCommunicator() const { return communicator; }
/** /**
* \brief Overload operator == * \brief Overload operator ==
* \details Overload operator comm1 == comm2. Two MPI objects are == if they share the same * \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; bool operator==(const MPI &) const;
/** /**
* \brief Overload operator != * \brief Overload operator !=
* \details Overload operator comm1 != comm2. Two MPI objects are != if they * \details Overload operator comm1 != comm2. Two MPI objects are != if they
@ -312,7 +286,6 @@ public: // Member functions
*/ */
bool operator!=(const MPI &) const; bool operator!=(const MPI &) const;
/** /**
* \brief Overload operator < * \brief Overload operator <
* \details Overload operator comm1 < comm2. One MPI object is < another iff all the * \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; bool operator<(const MPI &) const;
/** /**
* \brief Overload operator <= * \brief Overload operator <=
* \details Overload operator comm1 <= comm2. One MPI object is <= another iff all the * \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; bool operator<=(const MPI &) const;
/** /**
* \brief Overload operator > * \brief Overload operator >
* \details Overload operator comm1 > comm2. One MPI object is > another iff all the * \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; bool operator>(const MPI &) const;
/** /**
* \brief Overload operator >= * \brief Overload operator >=
* \details Overload operator comm1 >= comm2. One MPI object is > another iff all the * \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; bool operator>=(const MPI &) const;
/** /**
* \brief Compare to another communicator * \brief Compare to another communicator
* \details This compares the current communicator to another communicator. * \details This compares the current communicator to another communicator.
@ -378,26 +347,22 @@ public: // Member functions
*/ */
int compare(const MPI &) const; int compare(const MPI &) const;
/** /**
* Return the processor rank (identifier) from 0 through the number of * Return the processor rank (identifier) from 0 through the number of
* processors minus one. * processors minus one.
*/ */
int getRank() const { return comm_rank; } int getRank() const { return comm_rank; }
/** /**
* Return the number of processors. * Return the number of processors.
*/ */
int getSize() const { return comm_size; } int getSize() const { return comm_size; }
/** /**
* Return the maximum tag * Return the maximum tag
*/ */
int maxTag() const { return d_maxTag; } int maxTag() const { return d_maxTag; }
/** /**
* \brief Return a new tag * \brief Return a new tag
* \details This routine will return an unused tag for communication. * \details This routine will return an unused tag for communication.
@ -406,7 +371,6 @@ public: // Member functions
*/ */
int newTag(); int newTag();
/** /**
* Call MPI_Abort or exit depending on whether running with one or more * 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 * processes and value set by function above, if called. The default is
@ -416,7 +380,6 @@ public: // Member functions
*/ */
void abort() const; void abort() const;
/** /**
* Set boolean flag indicating whether exit or abort is called when running * Set boolean flag indicating whether exit or abort is called when running
* with one processor. Calling this function influences the behavior of * with one processor. Calling this function influences the behavior of
@ -425,7 +388,6 @@ public: // Member functions
*/ */
void setCallAbortInSerialInsteadOfExit(bool flag = true); void setCallAbortInSerialInsteadOfExit(bool flag = true);
/** /**
* \brief Boolean all reduce * \brief Boolean all reduce
* \details This function performs a boolean all reduce across all processors. * \details This function performs a boolean all reduce across all processors.
@ -434,7 +396,6 @@ public: // Member functions
*/ */
bool allReduce(const bool value) const; bool allReduce(const bool value) const;
/** /**
* \brief Boolean any reduce * \brief Boolean any reduce
* \details This function performs a boolean any reduce across all processors. * \details This function performs a boolean any reduce across all processors.
@ -443,16 +404,13 @@ public: // Member functions
*/ */
bool anyReduce(const bool value) const; bool anyReduce(const bool value) const;
/** /**
* \brief Sum Reduce * \brief Sum Reduce
* \details This function performs a sum all reduce across all processor. * \details This function performs a sum all reduce across all processor.
* It returns the sum across all processors; * It returns the sum across all processors;
* \param value The input value for the all reduce * \param value The input value for the all reduce
*/ */
template<class type> template <class type> type sumReduce(const type value) const;
type sumReduce( const type value ) const;
/** /**
* \brief Sum Reduce * \brief Sum Reduce
@ -462,9 +420,7 @@ public: // Member functions
* \param x The input/output array for the reduce * \param x The input/output array for the reduce
* \param n The number of values in the array (must match on all nodes) * \param n The number of values in the array (must match on all nodes)
*/ */
template<class type> template <class type> void sumReduce(type *x, const int n = 1) const;
void sumReduce( type *x, const int n = 1 ) const;
/** /**
* \brief Sum Reduce * \brief Sum Reduce
@ -478,16 +434,13 @@ public: // Member functions
template <class type> template <class type>
void sumReduce(const type *x, type *y, const int n = 1) const; void sumReduce(const type *x, type *y, const int n = 1) const;
/** /**
* \brief Min Reduce * \brief Min Reduce
* \details This function performs a min all reduce across all processor. * \details This function performs a min all reduce across all processor.
* It returns the minimum value across all processors; * It returns the minimum value across all processors;
* \param value The input value for the all reduce * \param value The input value for the all reduce
*/ */
template<class type> template <class type> type minReduce(const type value) const;
type minReduce( const type value ) const;
/** /**
* \brief Sum Reduce * \brief Sum Reduce
@ -506,7 +459,6 @@ public: // Member functions
template <class type> template <class type>
void minReduce(type *x, const int n = 1, int *rank_of_min = nullptr) const; void minReduce(type *x, const int n = 1, int *rank_of_min = nullptr) const;
/** /**
* \brief Sum Reduce * \brief Sum Reduce
* \details Perform an array min Reduce across all nodes. Each * \details Perform an array min Reduce across all nodes. Each
@ -523,8 +475,8 @@ public: // Member functions
* minimum value * minimum value
*/ */
template <class type> 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 * \brief Max Reduce
@ -532,9 +484,7 @@ public: // Member functions
* It returns the maximum value across all processors; * It returns the maximum value across all processors;
* \param value The input value for the all reduce * \param value The input value for the all reduce
*/ */
template<class type> template <class type> type maxReduce(const type value) const;
type maxReduce( const type value ) const;
/** /**
* \brief Sum Reduce * \brief Sum Reduce
@ -553,7 +503,6 @@ public: // Member functions
template <class type> template <class type>
void maxReduce(type *x, const int n = 1, int *rank_of_max = nullptr) const; void maxReduce(type *x, const int n = 1, int *rank_of_max = nullptr) const;
/** /**
* \brief Sum Reduce * \brief Sum Reduce
* \details Perform an array max Reduce across all nodes. Each * \details Perform an array max Reduce across all nodes. Each
@ -570,8 +519,8 @@ public: // Member functions
* minimum value * minimum value
*/ */
template <class type> 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 * \brief Scan Sum Reduce
@ -584,7 +533,6 @@ public: // Member functions
template <class type> template <class type>
void sumScan(const type *x, type *y, const int n = 1) const; void sumScan(const type *x, type *y, const int n = 1) const;
/** /**
* \brief Scan Min Reduce * \brief Scan Min Reduce
* \details Computes the min scan (partial reductions) of data on a collection of processes. * \details Computes the min scan (partial reductions) of data on a collection of processes.
@ -596,7 +544,6 @@ public: // Member functions
template <class type> template <class type>
void minScan(const type *x, type *y, const int n = 1) const; void minScan(const type *x, type *y, const int n = 1) const;
/** /**
* \brief Scan Max Reduce * \brief Scan Max Reduce
* \details Computes the max scan (partial reductions) of data on a collection of processes. * \details Computes the max scan (partial reductions) of data on a collection of processes.
@ -608,16 +555,13 @@ public: // Member functions
template <class type> template <class type>
void maxScan(const type *x, type *y, const int n = 1) const; void maxScan(const type *x, type *y, const int n = 1) const;
/** /**
* \brief Broadcast * \brief Broadcast
* \details This function broadcasts a value from root to all processors * \details This function broadcasts a value from root to all processors
* \param value The input value for the broadcast. * \param value The input value for the broadcast.
* \param root The processor performing the broadcast * \param root The processor performing the broadcast
*/ */
template<class type> template <class type> type bcast(const type &value, const int root) const;
type bcast( const type &value, const int root ) const;
/** /**
* \brief Broadcast * \brief Broadcast
@ -629,13 +573,11 @@ public: // Member functions
template <class type> template <class type>
void bcast(type *value, const int n, const int root) const; void bcast(type *value, const int n, const int root) const;
/** /**
* Perform a global barrier across all processors. * Perform a global barrier across all processors.
*/ */
void barrier() const; void barrier() const;
/*! /*!
* @brief This function sends an MPI message with an array to another processor. * @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. * The matching recv must share this tag.
*/ */
template <class type> 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 * @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. * to be sent with this message. Default tag is 0.
* The matching recv must share this tag. * 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 * @brief This function sends an MPI message with an array
@ -685,9 +627,8 @@ public: // Member functions
* to be sent with this message. * to be sent with this message.
*/ */
template <class type> template <class type>
MPI_Request Isend( MPI_Request Isend(const type *buf, const int length, const int recv_proc,
const type *buf, const int length, const int recv_proc, const int tag ) const; const int tag) const;
/*! /*!
* @brief This function sends an MPI message with an array of bytes * @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 * @param tag Integer argument specifying an integer tag
* to be sent with this message. * to be sent with this message.
*/ */
MPI_Request IsendBytes( MPI_Request IsendBytes(const void *buf, const int N_bytes,
const void *buf, const int N_bytes, const int recv_proc, const int tag ) const; const int recv_proc, const int tag) const;
/*! /*!
* @brief This function receives an MPI message with a data * @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. * by the tag of the incoming message. Default tag is 0.
*/ */
template <class type> 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; int length2 = length;
recv(buf, length2, send, false, tag); recv(buf, length2, send, false, tag);
} }
/*! /*!
* @brief This function receives an MPI message with a data * @brief This function receives an MPI message with a data
* array from another processor. * array from another processor.
@ -749,8 +687,8 @@ public: // Member functions
* by the tag of the incoming message. Default tag is 0. * by the tag of the incoming message. Default tag is 0.
*/ */
template <class type> 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 * @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; void recvBytes(void *buf, int &N_bytes, const int send, int tag = 0) const;
/*! /*!
* @brief This function receives an MPI message with a data * @brief This function receives an MPI message with a data
* array from another processor using a non-blocking call. * 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. * be matched by the tag of the incoming message.
*/ */
template <class type> 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 * @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 * @param tag Integer argument specifying a tag which must
* be matched by the tag of the incoming message. * be matched by the tag of the incoming message.
*/ */
MPI_Request IrecvBytes( MPI_Request IrecvBytes(void *buf, const int N_bytes, const int send_proc,
void *buf, const int N_bytes, const int send_proc, const int tag ) const; const int tag) const;
/*! /*!
* @brief This function sends and recieves data using a blocking call * @brief This function sends and recieves data using a blocking call
*/ */
template <class type> template <class type>
void sendrecv( const type *sendbuf, int sendcount, int dest, int sendtag, type *recvbuf, void sendrecv(const type *sendbuf, int sendcount, int dest, int sendtag,
int recvcount, int source, int recvtag ) const; type *recvbuf, int recvcount, int source, int recvtag) const;
/*! /*!
* Each processor sends every other processor a single value. * Each processor sends every other processor a single value.
* @param[in] x Input value for allGather * @param[in] x Input value for allGather
* @return Output array for allGather * @return Output array for allGather
*/ */
template<class type> template <class type> std::vector<type> allGather(const type &x) const;
std::vector<type> allGather( const type &x ) const;
/*! /*!
* Each processor sends every other processor an array * Each processor sends every other processor an array
@ -823,7 +756,6 @@ public: // Member functions
template <class type> template <class type>
std::vector<type> allGather(const std::vector<type> &x) const; std::vector<type> allGather(const std::vector<type> &x) const;
/*! /*!
* Each processor sends every other processor a single value. * Each processor sends every other processor a single value.
* The x_out array should be preallocated to a length equal * 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 * @param x_out Output array for allGather (must be preallocated to the size of the
* communicator) * communicator)
*/ */
template<class type> template <class type> void allGather(const type &x_in, type *x_out) const;
void allGather( const type &x_in, type *x_out ) const;
/*! /*!
* Each processor sends an array of data to all other processors. * Each processor sends an array of data to all other processors.
@ -863,16 +793,14 @@ public: // Member functions
*/ */
template <class type> template <class type>
int allGather(const type *send_data, const int send_cnt, type *recv_data, 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 * This function combines sets from different processors to create a single master set
* @param set Input/Output std::set for the gather. * @param set Input/Output std::set for the gather.
*/ */
template<class type> template <class type> void setGather(std::set<type> &set) const;
void setGather( std::set<type> &set ) const;
/*! /*!
* This function combines std::maps from different processors to create a single master std::map * 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> template <class KEY, class DATA>
void mapGather(std::map<KEY, DATA> &map) const; 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.
* 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> template <class type>
void allToAll(const int n, const type *send_data, type *recv_data) const; 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 sends an array of data to the different processors.
* Each processor may send any size array to any processor. In the variable * 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). * and the sizes and displacements will be returned (if desired).
*/ */
template <class type> template <class type>
int allToAll( const type *send_data, const int send_cnt[], const int send_disp[], int allToAll(const type *send_data, const int send_cnt[],
type *recv_data, int *recv_cnt = nullptr, int *recv_disp = nullptr, const int send_disp[], type *recv_data,
int *recv_cnt = nullptr, int *recv_disp = nullptr,
bool known_recv = false) const; bool known_recv = false) const;
/*! /*!
* \brief Send a list of proccesor ids to communicate * \brief Send a list of proccesor ids to communicate
* \details This function communicates a list of proccesors 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; std::vector<int> commRanks(const std::vector<int> &ranks) const;
/*! /*!
* \brief Wait for a communication to finish * \brief Wait for a communication to finish
* \details 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); static void wait(MPI_Request request);
/*! /*!
* \brief Wait for any communication to finish. * \brief Wait for any communication to finish.
* \details This function waits for any of the given communication requests 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); static int waitAny(int count, MPI_Request *request);
/*! /*!
* \brief Wait for all communications to finish. * \brief Wait for all communications to finish.
* \details This function waits for all of the given communication requests 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); static void waitAll(int count, MPI_Request *request);
/*! /*!
* \brief Wait for some communications to finish. * \brief Wait for some communications to finish.
* \details This function waits for one (or more) 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); static std::vector<int> waitSome(int count, MPI_Request *request);
/*! /*!
* \brief Nonblocking test for a message * \brief Nonblocking test for a message
* \details This function performs a non-blocking 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; int Iprobe(int source = -1, int tag = -1) const;
/*! /*!
* \brief Blocking test for a message * \brief Blocking test for a message
* \details This function performs a 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; int probe(int source = -1, int tag = -1) const;
/*! /*!
* \brief Start a serial region * \brief Start a serial region
* \details This function will serialize MPI processes so that they run * \details This function will serialize MPI processes so that they run
@ -1018,14 +937,12 @@ public: // Member functions
*/ */
void serializeStart(); void serializeStart();
/*! /*!
* \brief Stop a serial region * \brief Stop a serial region
* \details Stop a serial region. See serializeStart for more information. * \details Stop a serial region. See serializeStart for more information.
*/ */
void serializeStop(); void serializeStop();
/*! /*!
* \brief Elapsed time * \brief Elapsed time
* \details This function returns the elapsed time on the calling processor * \details This function returns the elapsed time on the calling processor
@ -1036,14 +953,12 @@ public: // Member functions
*/ */
static double time(); static double time();
/*! /*!
* \brief Timer resolution * \brief Timer resolution
* \details This function returns the timer resolution used by "time" * \details This function returns the timer resolution used by "time"
*/ */
static double tick(); static double tick();
/*! /*!
* \brief Change the level of the internal timers * \brief Change the level of the internal timers
* \details This function changes the level of the timers used to profile MPI * \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; } static void changeProfileLevel(int level) { profile_level = level; }
//! Return the total number of MPI_Comm objects that have been created //! Return the total number of MPI_Comm objects that have been created
static size_t MPI_Comm_created() { return N_MPI_Comm_created; } static size_t MPI_Comm_created() { return N_MPI_Comm_created; }
@ -1073,7 +987,6 @@ public: // Member functions
//! Stop MPI //! Stop MPI
static void stop_MPI(); static void stop_MPI();
/*! /*!
* \brief Load balance * \brief Load balance
* \details This function will return a new communicator in which the ranks match * \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); MPI loadBalance(double localPerformance, std::vector<double> work);
private: // Private helper functions for templated MPI operations; private: // Private helper functions for templated MPI operations;
template<class type> template <class type> void call_sumReduce(type *x, const int n = 1) const;
void call_sumReduce( type *x, const int n = 1 ) const;
template <class type> template <class type>
void call_sumReduce(const type *x, type *y, const int n = 1) const; void call_sumReduce(const type *x, type *y, const int n = 1) const;
template <class type> 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> template <class type>
void call_minReduce( void call_minReduce(const type *x, type *y, const int n = 1,
const type *x, type *y, const int n = 1, int *rank_of_min = nullptr ) const; int *rank_of_min = nullptr) const;
template <class type> 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> template <class type>
void call_maxReduce( void call_maxReduce(const type *x, type *y, const int n = 1,
const type *x, type *y, const int n = 1, int *rank_of_max = nullptr ) const; int *rank_of_max = nullptr) const;
template <class type> template <class type>
void call_bcast(type *x, const int n, const int root) const; void call_bcast(type *x, const int n, const int root) const;
template <class type> template <class type>
void call_allGather(const type &x_in, type *x_out) const; void call_allGather(const type &x_in, type *x_out) const;
template <class type> template <class type>
void call_allGather( void call_allGather(const type *x_in, int size_in, type *x_out,
const type *x_in, int size_in, type *x_out, int *size_out, int *disp_out ) const; int *size_out, int *disp_out) const;
template <class type> template <class type>
void call_sumScan(const type *x, type *y, int n = 1) const; void call_sumScan(const type *x, type *y, int n = 1) const;
template <class type> template <class type>
@ -1110,9 +1024,9 @@ private: // Private helper functions for templated MPI operations;
template <class type> template <class type>
void call_maxScan(const type *x, type *y, int n = 1) const; void call_maxScan(const type *x, type *y, int n = 1) const;
template <class type> template <class type>
void call_allToAll( const type *send_data, const int send_cnt[], const int send_disp[], void call_allToAll(const type *send_data, const int send_cnt[],
type *recv_data, const int *recv_cnt, const int *recv_disp ) const; const int send_disp[], type *recv_data,
const int *recv_cnt, const int *recv_disp) const;
private: // data members private: // data members
// The internal MPI communicator // The internal MPI communicator
@ -1157,14 +1071,11 @@ private: // data members
static volatile unsigned int N_MPI_Comm_destroyed; static volatile unsigned int N_MPI_Comm_destroyed;
}; };
} // namespace Utilities } // namespace Utilities
// Include the default instantiations // Include the default instantiations
// \cond HIDDEN_SYMBOLS // \cond HIDDEN_SYMBOLS
#include "common/MPI.I" #include "common/MPI.I"
// \endcond // \endcond
#endif #endif

View File

@ -5,10 +5,8 @@
#include <cstring> #include <cstring>
// Read a file into memory // 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"); auto fid = fopen(filename.c_str(), "rb");
INSIST(fid, "File does not exist: " + filename); INSIST(fid, "File does not exist: " + filename);
fseek(fid, 0, SEEK_END); fseek(fid, 0, SEEK_END);
@ -21,10 +19,8 @@ std::vector<char> readFile( const std::string& filename )
return data; return data;
} }
// Decompress a gzip buffer // 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; z_stream stream;
std::vector<char> out(1000000); std::vector<char> out(1000000);
stream.next_in = (Bytef *)in.data(); stream.next_in = (Bytef *)in.data();
@ -50,10 +46,8 @@ std::vector<char> gunzip( const std::vector<char>& in )
return out; return out;
} }
// Read the compressed micro CT data // 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 in = readFile(filename);
auto out = gunzip(in); auto out = gunzip(in);
ASSERT(out.size() == 1024 * 1024 * 1024); ASSERT(out.size() == 1024 * 1024 * 1024);
@ -62,10 +56,8 @@ Array<uint8_t> readMicroCT( const std::string& filename )
return data; return data;
} }
// Read the compressed micro CT data and distribute // 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 // Get the local problem info
auto n = domain.getVector<int>("n"); auto n = domain.getVector<int>("n");
int rank = comm.getRank(); 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"); auto filename = domain.getScalar<std::string>("Filename");
char tmp[100]; char tmp[100];
if (filename.find("0x_0y_0z.gbd.gz") != std::string::npos) { if (filename.find("0x_0y_0z.gbd.gz") != std::string::npos) {
sprintf( tmp, "%ix_%iy_%iz.gbd.gz", srcRankInfo.ix, srcRankInfo.jy, srcRankInfo.kz ); sprintf(tmp, "%ix_%iy_%iz.gbd.gz", srcRankInfo.ix, srcRankInfo.jy,
filename = filename.replace( filename.find( "0x_0y_0z.gbd.gz" ), 15, std::string( tmp ) ); 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) { } 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 ); sprintf(tmp, "x%i_y%i_z%i.gbd.gz", srcRankInfo.ix, srcRankInfo.jy,
filename = filename.replace( filename.find( "x0_y0_z0.gbd.gz" ), 15, std::string( tmp ) ); srcRankInfo.kz);
filename = filename.replace(filename.find("x0_y0_z0.gbd.gz"), 15,
std::string(tmp));
} else { } else {
ERROR("Invalid name for first file"); ERROR("Invalid name for first file");
} }

View File

@ -1,16 +1,13 @@
#ifndef READMICROCT_H #ifndef READMICROCT_H
#define READMICROCT_H #define READMICROCT_H
#include "common/Array.h" #include "common/Array.h"
#include "common/Communication.h" #include "common/Communication.h"
#include "common/Database.h" #include "common/Database.h"
#include "common/MPI.h" #include "common/MPI.h"
Array<uint8_t> readMicroCT(const std::string &filename); Array<uint8_t> readMicroCT(const std::string &filename);
Array<uint8_t> readMicroCT(const Database &domain, const Utilities::MPI &comm); Array<uint8_t> readMicroCT(const Database &domain, const Utilities::MPI &comm);
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -47,14 +47,15 @@
#include "common/SpherePack.h" #include "common/SpherePack.h"
// Inline function to read line without a return argument // 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); 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; char value;
ofstream File(FILENAME, ios::binary); ofstream File(FILENAME, ios::binary);
for (int n = 0; n < N; n++) { for (int n = 0; n < N; n++) {
@ -64,8 +65,7 @@ void WriteLocalSolidID(char *FILENAME, char *ID, int N)
File.close(); File.close();
} }
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N) void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N) {
{
double value; double value;
ofstream File(FILENAME, ios::binary); ofstream File(FILENAME, ios::binary);
for (int n = 0; n < N; n++) { for (int n = 0; n < N; n++) {
@ -75,8 +75,8 @@ void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N)
File.close(); 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 full sphere pack
//...... READ IN THE SPHERES................................... //...... READ IN THE SPHERES...................................
cout << "Reading the packing file..." << endl; cout << "Reading the packing file..." << endl;
@ -101,14 +101,16 @@ void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *L
count++; count++;
} }
cout << "Number of spheres extracted is: " << count << endl; 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, 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 // Use sphere lists to determine which nodes are in porespace
// Write out binary file for nodes // Write out binary file for nodes
char value; char value;
@ -163,18 +165,30 @@ void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy
kmin = int((cz - r) / hz) - 1; kmin = int((cz - r) / hz) - 1;
kmax = int((cz + r) / hz) + 1; kmax = int((cz + r) / hz) + 1;
// Obviously we have to do something at the edges // Obviously we have to do something at the edges
if (imin<0) imin = 0; if (imin < 0)
if (imin>Nx) imin = Nx; imin = 0;
if (imax<0) imax = 0; if (imin > Nx)
if (imax>Nx) imax = Nx; imin = Nx;
if (jmin<0) jmin = 0; if (imax < 0)
if (jmin>Ny) jmin = Ny; imax = 0;
if (jmax<0) jmax = 0; if (imax > Nx)
if (jmax>Ny) jmax = Ny; imax = Nx;
if (kmin<0) kmin = 0; if (jmin < 0)
if (kmin>Nz) kmin = Nz; jmin = 0;
if (kmax<0) kmax = 0; if (jmin > Ny)
if (kmax>Nz) kmax = Nz; 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) // Loop over the domain for this sphere (may be null)
for (i = imin; i < imax; i++) { for (i = imin; i < imax; i++) {
for (j = jmin; j < jmax; j++) { for (j = jmin; j < jmax; j++) {
@ -185,7 +199,9 @@ void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy
z = k * hz; z = k * hz;
value = 1; value = 1;
// if inside sphere, set to zero // 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; value = 0;
} }
// get the position in the list // get the position in the list
@ -199,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, 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 // Use sphere lists to determine which nodes are in porespace
// Write out binary file for nodes // Write out binary file for nodes
int N = Nx * Ny * Nz; // Domain size, including the halo int N = Nx * Ny * Nz; // Domain size, including the halo
@ -253,18 +270,30 @@ void SignedDistance(double *Distance, int nspheres, double *List_cx, double *Lis
kmin = int((cz - 2 * r) / hz); kmin = int((cz - 2 * r) / hz);
kmax = int((cz + 2 * r) / hz) + 2; kmax = int((cz + 2 * r) / hz) + 2;
// Obviously we have to do something at the edges // Obviously we have to do something at the edges
if (imin<0) imin = 0; if (imin < 0)
if (imin>Nx) imin = Nx; imin = 0;
if (imax<0) imax = 0; if (imin > Nx)
if (imax>Nx) imax = Nx; imin = Nx;
if (jmin<0) jmin = 0; if (imax < 0)
if (jmin>Ny) jmin = Ny; imax = 0;
if (jmax<0) jmax = 0; if (imax > Nx)
if (jmax>Ny) jmax = Ny; imax = Nx;
if (kmin<0) kmin = 0; if (jmin < 0)
if (kmin>Nz) kmin = Nz; jmin = 0;
if (kmax<0) kmax = 0; if (jmin > Ny)
if (kmax>Nz) kmax = Nz; 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) // Loop over the domain for this sphere (may be null)
for (i = imin; i < imax; i++) { for (i = imin; i < imax; i++) {
for (j = jmin; j < jmax; j++) { for (j = jmin; j < jmax; j++) {
@ -277,15 +306,18 @@ void SignedDistance(double *Distance, int nspheres, double *List_cx, double *Lis
// get the position in the list // get the position in the list
n = k * Nx * Ny + j * Nx + i; n = k * Nx * Ny + j * Nx + i;
// Compute the distance // 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 // Assign the minimum distance
if (distance < Distance[n]) Distance[n] = distance; if (distance < Distance[n])
Distance[n] = distance;
} }
} }
} }
} }
// Map the distance to lattice units // 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;
} }

View File

@ -40,14 +40,19 @@ void WriteLocalSolidID(char *FILENAME, char *ID, int N);
void WriteLocalSolidDistance(char *FILENAME, double *Distance, 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, 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, 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 #endif

View File

@ -22,23 +22,19 @@
#include <string> #include <string>
#include <vector> #include <vector>
#define pout std::cout #define pout std::cout
#define printp printf #define printp printf
/******************************************************************** /********************************************************************
* Constructor/Destructor * * Constructor/Destructor *
********************************************************************/ ********************************************************************/
UnitTest::UnitTest() UnitTest::UnitTest() {
{
#ifdef USE_MPI #ifdef USE_MPI
comm = MPI_COMM_WORLD; comm = MPI_COMM_WORLD;
#endif #endif
} }
UnitTest::~UnitTest() { reset(); } UnitTest::~UnitTest() { reset(); }
void UnitTest::reset() void UnitTest::reset() {
{
mutex.lock(); mutex.lock();
// Clear the data forcing a reallocation // Clear the data forcing a reallocation
std::vector<std::string>().swap(pass_messages); std::vector<std::string>().swap(pass_messages);
@ -47,36 +43,30 @@ void UnitTest::reset()
mutex.unlock(); mutex.unlock();
} }
/******************************************************************** /********************************************************************
* Add a pass, fail, expected failure message in a thread-safe way * * 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(); mutex.lock();
pass_messages.push_back(in); pass_messages.push_back(in);
mutex.unlock(); mutex.unlock();
} }
void UnitTest::failure( const std::string &in ) void UnitTest::failure(const std::string &in) {
{
mutex.lock(); mutex.lock();
fail_messages.push_back(in); fail_messages.push_back(in);
mutex.unlock(); mutex.unlock();
} }
void UnitTest::expected_failure( const std::string &in ) void UnitTest::expected_failure(const std::string &in) {
{
mutex.lock(); mutex.lock();
expected_fail_messages.push_back(in); expected_fail_messages.push_back(in);
mutex.unlock(); mutex.unlock();
} }
/******************************************************************** /********************************************************************
* Print a global report * * Print a global report *
* Note: only rank 0 will print, all messages will be aggregated * * 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(); int size = getSize();
std::vector<int> data(size, value); std::vector<int> data(size, value);
#ifdef USE_MPI #ifdef USE_MPI
@ -85,15 +75,14 @@ inline std::vector<int> UnitTest::allGather( int value ) const
#endif #endif
return data; return data;
} }
inline void UnitTest::barrier() const inline void UnitTest::barrier() const {
{
#ifdef USE_MPI #ifdef USE_MPI
if (getSize() > 1) if (getSize() > 1)
MPI_Barrier(comm); MPI_Barrier(comm);
#endif #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) { if (messages.size() > 1) {
for (size_t i = 0; i < messages.size(); i++) { for (size_t i = 0; i < messages.size(); i++) {
if (!messages[i].empty()) { if (!messages[i].empty()) {
@ -107,8 +96,7 @@ static inline void print_messages( const std::vector<std::vector<std::string>> &
pout << " " << j << std::endl; pout << " " << j << std::endl;
} }
} }
void UnitTest::report( const int level0 ) const void UnitTest::report(const int level0) const {
{
mutex.lock(); mutex.lock();
int size = getSize(); int size = getSize();
int rank = getRank(); int rank = getRank();
@ -144,7 +132,8 @@ void UnitTest::report( const int level0 ) const
fail_messages_rank = UnitTest::gatherMessages(fail_messages, 2); fail_messages_rank = UnitTest::gatherMessages(fail_messages, 2);
// Get the expected_fail messages // Get the expected_fail messages
if ((level == 1 && N_expected_fail_tot <= 50) || level == 2) 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) // Print the results of all messages (only rank 0 will print)
if (rank == 0) { if (rank == 0) {
pout << std::endl; pout << std::endl;
@ -154,11 +143,14 @@ void UnitTest::report( const int level0 ) const
// We want to print a summary // We want to print a summary
if (size > 8) { if (size > 8) {
// Print 1 summary for all processors // 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 { } else {
// Print a summary for each processor // Print a summary for each processor
for (int i = 0; i < size; i++) 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); N_pass[i], i);
} }
} else { } else {
@ -174,11 +166,14 @@ void UnitTest::report( const int level0 ) const
// We want to print a summary // We want to print a summary
if (size > 8) { if (size > 8) {
// Print 1 summary for all processors // 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 { } else {
// Print a summary for each processor // Print a summary for each processor
for (int i = 0; i < size; i++) 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); N_fail[i], i);
} }
} else { } else {
@ -194,12 +189,14 @@ void UnitTest::report( const int level0 ) const
// We want to print a summary // We want to print a summary
if (size > 8) { if (size > 8) {
// Print 1 summary for all processors // 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); N_expected_fail_tot);
} else { } else {
// Print a summary for each processor // Print a summary for each processor
for (int i = 0; i < size; i++) 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", "detail)\n",
N_expected_fail[i], i); N_expected_fail[i], i);
} }
@ -213,17 +210,17 @@ void UnitTest::report( const int level0 ) const
} }
// Add a barrier to synchronize all processors (rank 0 is much slower) // Add a barrier to synchronize all processors (rank 0 is much slower)
barrier(); 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(); mutex.unlock();
} }
/******************************************************************** /********************************************************************
* Gather the messages to rank 0 * * Gather the messages to rank 0 *
********************************************************************/ ********************************************************************/
std::vector<std::vector<std::string>> UnitTest::gatherMessages( std::vector<std::vector<std::string>>
const std::vector<std::string> &local_messages, int tag ) const UnitTest::gatherMessages(const std::vector<std::string> &local_messages,
{ int tag) const {
const int rank = getRank(); const int rank = getRank();
const int size = getSize(); const int size = getSize();
std::vector<std::vector<std::string>> messages(size); std::vector<std::vector<std::string>> messages(size);
@ -242,13 +239,11 @@ std::vector<std::vector<std::string>> UnitTest::gatherMessages(
return messages; return messages;
} }
/******************************************************************** /********************************************************************
* Pack and send the given messages * * Pack and send the given messages *
********************************************************************/ ********************************************************************/
void UnitTest::pack_message_stream( void UnitTest::pack_message_stream(const std::vector<std::string> &messages,
const std::vector<std::string> &messages, const int rank, const int tag ) const const int rank, const int tag) const {
{
#ifdef USE_MPI #ifdef USE_MPI
// Get the size of the messages // Get the size of the messages
auto N_messages = (int)messages.size(); auto N_messages = (int)messages.size();
@ -284,12 +279,11 @@ void UnitTest::pack_message_stream(
#endif #endif
} }
/******************************************************************** /********************************************************************
* Receive and unpack a message stream * * 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 #ifdef USE_MPI
// Probe the message to get the message size // Probe the message to get the message size
MPI_Status status; MPI_Status status;
@ -328,12 +322,10 @@ std::vector<std::string> UnitTest::unpack_message_stream( const int rank, const
#endif #endif
} }
/******************************************************************** /********************************************************************
* Other functions * * Other functions *
********************************************************************/ ********************************************************************/
int UnitTest::getRank() const int UnitTest::getRank() const {
{
int rank = 0; int rank = 0;
#ifdef USE_MPI #ifdef USE_MPI
int flag = 0; int flag = 0;
@ -343,8 +335,7 @@ int UnitTest::getRank() const
#endif #endif
return rank; return rank;
} }
int UnitTest::getSize() const int UnitTest::getSize() const {
{
int size = 1; int size = 1;
#ifdef USE_MPI #ifdef USE_MPI
int flag = 0; int flag = 0;
@ -354,8 +345,7 @@ int UnitTest::getSize() const
#endif #endif
return size; return size;
} }
size_t UnitTest::NumPassGlobal() const size_t UnitTest::NumPassGlobal() const {
{
size_t num = pass_messages.size(); size_t num = pass_messages.size();
#ifdef USE_MPI #ifdef USE_MPI
if (getSize() > 1) { if (getSize() > 1) {
@ -367,8 +357,7 @@ size_t UnitTest::NumPassGlobal() const
#endif #endif
return num; return num;
} }
size_t UnitTest::NumFailGlobal() const size_t UnitTest::NumFailGlobal() const {
{
size_t num = fail_messages.size(); size_t num = fail_messages.size();
#ifdef USE_MPI #ifdef USE_MPI
if (getSize() > 1) { if (getSize() > 1) {
@ -380,8 +369,7 @@ size_t UnitTest::NumFailGlobal() const
#endif #endif
return num; return num;
} }
size_t UnitTest::NumExpectedFailGlobal() const size_t UnitTest::NumExpectedFailGlobal() const {
{
size_t num = expected_fail_messages.size(); size_t num = expected_fail_messages.size();
#ifdef USE_MPI #ifdef USE_MPI
if (getSize() > 1) { if (getSize() > 1) {

View File

@ -25,7 +25,6 @@
#include "mpi.h" #include "mpi.h"
#endif #endif
/*! /*!
* @brief Class UnitTest is simple utility for running unit tests. * @brief Class UnitTest is simple utility for running unit tests.
* It provides basic routines for tracing success or failure of tests, * It provides basic routines for tracing success or failure of tests,
@ -44,8 +43,7 @@
* \endcode * \endcode
*/ */
class UnitTest class UnitTest {
{
public: public:
//! Constructor //! Constructor
UnitTest(); UnitTest();
@ -69,7 +67,9 @@ public:
virtual size_t NumFailLocal() const { return fail_messages.size(); } virtual size_t NumFailLocal() const { return fail_messages.size(); }
//! Return the number of expected failed tests locally //! 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 //! Return the number of passed tests locally
virtual size_t NumPassGlobal() const; virtual size_t NumPassGlobal() const;
@ -118,19 +118,20 @@ private:
// Function to pack the messages into a single data stream and send to the given processor // 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 // Note: This function does not return until the message stream has been sent
void pack_message_stream( void pack_message_stream(const std::vector<std::string> &messages,
const std::vector<std::string> &messages, const int rank, const int tag ) const; const int rank, const int tag) const;
// Function to unpack the messages from a single data stream // Function to unpack the messages from a single data stream
// Note: This function does not return until the message stream has been received // 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 // Helper functions
inline void barrier() const; inline void barrier() const;
inline std::vector<int> allGather(int value) const; inline std::vector<int> allGather(int value) const;
inline std::vector<std::vector<std::string>> gatherMessages( inline std::vector<std::vector<std::string>>
const std::vector<std::string> &local_messages, int tag ) const; gatherMessages(const std::vector<std::string> &local_messages,
int tag) const;
}; };
#endif #endif

View File

@ -21,19 +21,16 @@
#include <cmath> #include <cmath>
#include <string> #include <string>
constexpr double Units::d_pow10[22]; constexpr double Units::d_pow10[22];
constexpr char Units::d_prefixSymbol[]; constexpr char Units::d_prefixSymbol[];
/******************************************************************** /********************************************************************
* Constructors * * Constructors *
********************************************************************/ ********************************************************************/
Units::Units() : d_prefix(UnitPrefix::unknown), d_unit(UnitValue::unknown) {} Units::Units() : d_prefix(UnitPrefix::unknown), d_unit(UnitValue::unknown) {}
Units::Units(UnitPrefix p, UnitValue u) : d_prefix(p), d_unit(u) {} Units::Units(UnitPrefix p, UnitValue u) : d_prefix(p), d_unit(u) {}
Units::Units(const std::string &unit) 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 // Parse the string to get it into a more friendly format
auto tmp = unit; auto tmp = unit;
tmp.erase(std::remove(tmp.begin(), tmp.end(), ' '), tmp.end()); tmp.erase(std::remove(tmp.begin(), tmp.end(), ' '), tmp.end());
@ -52,7 +49,8 @@ Units::Units( const std::string& unit )
} else { } else {
d_prefix = getUnitPrefix(tmp.substr(0, 1)); d_prefix = getUnitPrefix(tmp.substr(0, 1));
d_unit = getUnitValue(tmp.substr(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_prefix = UnitPrefix::none;
d_unit = getUnitValue(tmp); d_unit = getUnitValue(tmp);
} }
@ -60,12 +58,10 @@ Units::Units( const std::string& unit )
} }
} }
/******************************************************************** /********************************************************************
* Get prefix * * 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; Units::UnitPrefix value = UnitPrefix::unknown;
if (str.empty()) { if (str.empty()) {
value = UnitPrefix::none; value = UnitPrefix::none;
@ -113,12 +109,10 @@ Units::UnitPrefix Units::getUnitPrefix( const std::string& str ) noexcept
return value; return value;
} }
/******************************************************************** /********************************************************************
* Get unit 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; Units::UnitValue value = UnitValue::unknown;
if (str == "meter" || str == "m") { if (str == "meter" || str == "m") {
value = UnitValue::meter; value = UnitValue::meter;
@ -142,12 +136,10 @@ Units::UnitValue Units::getUnitValue( const std::string& str ) noexcept
return value; return value;
} }
/******************************************************************** /********************************************************************
* Get unit type * * Get unit type *
********************************************************************/ ********************************************************************/
Units::UnitType Units::getUnitType( UnitValue u ) noexcept Units::UnitType Units::getUnitType(UnitValue u) noexcept {
{
switch (u) { switch (u) {
case UnitValue::meter: case UnitValue::meter:
return UnitType::length; return UnitType::length;
@ -170,12 +162,10 @@ Units::UnitType Units::getUnitType( UnitValue u ) noexcept
} }
} }
/******************************************************************** /********************************************************************
* Convert to another unit system * * 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)) if (this->operator==(rhs))
return 1; return 1;
// Convert the prefix // Convert the prefix
@ -198,17 +188,14 @@ double Units::convert( const Units& rhs ) const noexcept
return cp * cu; return cp * cu;
} }
/******************************************************************** /********************************************************************
* Write a string for the units * * Write a string for the units *
********************************************************************/ ********************************************************************/
std::string Units::str() const std::string Units::str() const {
{
ASSERT(!isNull()); ASSERT(!isNull());
return std::string(str(d_prefix).data()) + str(d_unit); 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; std::array<char, 3> str;
str[0] = d_prefixSymbol[static_cast<int8_t>(p)]; str[0] = d_prefixSymbol[static_cast<int8_t>(p)];
str[1] = 0; str[1] = 0;
@ -217,8 +204,7 @@ std::array<char, 3> Units::str( UnitPrefix p ) noexcept
str[1] = 'a'; str[1] = 'a';
return str; return str;
} }
std::string Units::str( UnitValue u ) std::string Units::str(UnitValue u) {
{
if (u == UnitValue::meter) { if (u == UnitValue::meter) {
return "m"; return "m";
} else if (u == UnitValue::gram) { } else if (u == UnitValue::gram) {

View File

@ -24,10 +24,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
//! Unit system class //! Unit system class
class Units final class Units final {
{
public: public:
//! Enum to hold prefix //! Enum to hold prefix
enum class UnitPrefix : int8_t { enum class UnitPrefix : int8_t {
@ -81,7 +79,6 @@ public:
unknown unknown
}; };
public: public:
//! Constructor //! Constructor
Units(); Units();
@ -114,8 +111,7 @@ public:
double convert(const Units &) const noexcept; double convert(const Units &) const noexcept;
//! Convert a prefix to a scalar //! 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)]; return d_pow10[static_cast<int8_t>(x)];
} }
@ -129,27 +125,28 @@ public:
static std::string str(UnitValue); static std::string str(UnitValue);
//! Operator == //! 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; return d_prefix == rhs.d_prefix && d_unit == rhs.d_unit;
} }
//! Operator != //! 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; return d_prefix != rhs.d_prefix || d_unit != rhs.d_unit;
} }
//! Check if unit is null //! 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: protected:
UnitPrefix d_prefix; UnitPrefix d_prefix;
UnitValue d_unit; UnitValue d_unit;
private: private:
constexpr static double d_pow10[22] = { 1e-24, 1e-21, 1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3, constexpr static double d_pow10[22] = {
1e-2, 0.1, 1, 10, 100, 1000, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24, 0 }; 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"; constexpr static char d_prefixSymbol[] = "yzafpnumcd\0dhkMGTPEZYu";
}; };

View File

@ -31,7 +31,6 @@
#include <math.h> #include <math.h>
#include <mutex> #include <mutex>
// OS specific includes / definitions // OS specific includes / definitions
// clang-format off // clang-format off
#if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 ) #if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 )
@ -45,16 +44,13 @@
#endif #endif
// clang-format on // clang-format on
// Mutex for Utility functions // Mutex for Utility functions
static std::mutex Utilities_mutex; static std::mutex Utilities_mutex;
/**************************************************************************** /****************************************************************************
* Function to perform the default startup/shutdown sequences * * 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(argc);
NULL_USE(argv); NULL_USE(argv);
// Disable OpenMP // Disable OpenMP
@ -69,7 +65,9 @@ void Utilities::startup( int argc, char **argv, bool multiple )
int rank; int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0) 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); StackTrace::globalCallStackInitialize(MPI_COMM_WORLD);
} else { } else {
@ -80,8 +78,7 @@ void Utilities::startup( int argc, char **argv, bool multiple )
Utilities::setAbortBehavior(true, 3); Utilities::setAbortBehavior(true, 3);
Utilities::setErrorHandlers(); Utilities::setErrorHandlers();
} }
void Utilities::shutdown() void Utilities::shutdown() {
{
// Clear the error handlers // Clear the error handlers
Utilities::clearErrorHandlers(); Utilities::clearErrorHandlers();
StackTrace::clearSignals(); StackTrace::clearSignals();
@ -101,12 +98,10 @@ void Utilities::shutdown()
#endif #endif
} }
/**************************************************************************** /****************************************************************************
* Function to set an environemental variable * * 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(); Utilities_mutex.lock();
#if defined(USE_LINUX) || defined(USE_MAC) #if defined(USE_LINUX) || defined(USE_MAC)
bool pass = false; bool pass = false;
@ -123,15 +118,15 @@ void Utilities::setenv( const std::string &name, const std::string &value )
if (!pass) { if (!pass) {
char msg[1024]; char msg[1024];
if (!value.empty()) if (!value.empty())
sprintf( sprintf(msg, "Error setting enviornmental variable: %s=%s\n",
msg, "Error setting enviornmental variable: %s=%s\n", name.data(), value.data() ); name.data(), value.data());
else else
sprintf( msg, "Error clearing enviornmental variable: %s\n", name.data() ); sprintf(msg, "Error clearing enviornmental variable: %s\n",
name.data());
ERROR(msg); ERROR(msg);
} }
} }
std::string Utilities::getenv( const std::string &name ) std::string Utilities::getenv(const std::string &name) {
{
std::string var; std::string var;
Utilities_mutex.lock(); Utilities_mutex.lock();
auto tmp = std::getenv(name.data()); auto tmp = std::getenv(name.data());
@ -141,12 +136,10 @@ std::string Utilities::getenv( const std::string &name )
return var; return var;
} }
/**************************************************************************** /****************************************************************************
* Factor a number into it's prime factors * * 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) if (number <= 3)
return std::vector<int>(1, (int)number); return std::vector<int>(1, (int)number);
size_t i, n, n_max; size_t i, n, n_max;
@ -154,7 +147,8 @@ std::vector<int> Utilities::factor(size_t number)
// Compute the maximum number of factors // Compute the maximum number of factors
int N_primes_max = 1; int N_primes_max = 1;
n = number; n = number;
while (n >>= 1) ++N_primes_max; while (n >>= 1)
++N_primes_max;
// Initialize n, factors // Initialize n, factors
n = number; n = number;
std::vector<int> factors; std::vector<int> factors;
@ -193,14 +187,7 @@ std::vector<int> Utilities::factor(size_t number)
return factors; return factors;
} }
/**************************************************************************** /****************************************************************************
* Dummy function to prevent compiler from optimizing away variable * * Dummy function to prevent compiler from optimizing away variable *
****************************************************************************/ ****************************************************************************/
void Utilities::nullUse( void* data ) void Utilities::nullUse(void *data) { NULL_USE(data); }
{
NULL_USE(data);
}

View File

@ -22,10 +22,8 @@
#include "StackTrace/Utilities.h" #include "StackTrace/Utilities.h"
namespace Utilities { namespace Utilities {
// Functions inherited from StackTrace::Utilities // Functions inherited from StackTrace::Utilities
using StackTrace::Utilities::abort; using StackTrace::Utilities::abort;
using StackTrace::Utilities::cause_segfault; using StackTrace::Utilities::cause_segfault;
@ -35,11 +33,10 @@ using StackTrace::Utilities::getMemoryUsage;
using StackTrace::Utilities::getSystemMemory; using StackTrace::Utilities::getSystemMemory;
using StackTrace::Utilities::setAbortBehavior; using StackTrace::Utilities::setAbortBehavior;
using StackTrace::Utilities::setErrorHandlers; using StackTrace::Utilities::setErrorHandlers;
using StackTrace::Utilities::tick;
using StackTrace::Utilities::time;
using StackTrace::Utilities::sleep_ms; using StackTrace::Utilities::sleep_ms;
using StackTrace::Utilities::sleep_s; using StackTrace::Utilities::sleep_s;
using StackTrace::Utilities::tick;
using StackTrace::Utilities::time;
/*! /*!
* \brief Start MPI, error handlers * \brief Start MPI, error handlers
@ -56,7 +53,6 @@ void startup( int argc, char **argv, bool multiple=true );
*/ */
void shutdown(); void shutdown();
/*! /*!
* Get an environmental variable * Get an environmental variable
* @param name The name of the environmental variable * @param name The name of the environmental variable
@ -64,7 +60,6 @@ void shutdown();
*/ */
std::string getenv(const std::string &name); std::string getenv(const std::string &name);
/*! /*!
* Set an environmental variable * Set an environmental variable
* @param name The name of the environmental variable * @param name The name of the environmental variable
@ -72,28 +67,21 @@ std::string getenv( const std::string &name );
*/ */
void setenv(const std::string &name, const std::string &value); void setenv(const std::string &name, const std::string &value);
//! std::string version of sprintf //! std::string version of sprintf
inline std::string stringf(const char *format, ...); inline std::string stringf(const char *format, ...);
//! Factor a number into it's prime factors //! Factor a number into it's prime factors
std::vector<int> factor(size_t number); std::vector<int> factor(size_t number);
//! Null use function //! Null use function
void nullUse(void *); void nullUse(void *);
} // namespace Utilities } // namespace Utilities
#include "common/UtilityMacros.h" #include "common/UtilityMacros.h"
// stringf // stringf
inline std::string Utilities::stringf( const char *format, ... ) inline std::string Utilities::stringf(const char *format, ...) {
{
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
char tmp[4096]; char tmp[4096];
@ -102,5 +90,4 @@ inline std::string Utilities::stringf( const char *format, ... )
return std::string(tmp); return std::string(tmp);
} }
#endif #endif

View File

@ -1,21 +1,16 @@
#ifndef included_Utilities_hpp #ifndef included_Utilities_hpp
#define included_Utilities_hpp #define included_Utilities_hpp
#include "Utilities.h" #include "Utilities.h"
#include <vector> #include <vector>
namespace Utilities { namespace Utilities {
/************************************************************************ /************************************************************************
* templated quicksort routines * * templated quicksort routines *
************************************************************************/ ************************************************************************/
template<class T> template <class T> void quicksort(std::vector<T> &x) {
void quicksort( std::vector<T> &x )
{
if (x.size() <= 1u) if (x.size() <= 1u)
return; return;
T *arr = &x[0]; T *arr = &x[0];
@ -45,11 +40,13 @@ void quicksort( std::vector<T> &x )
} }
if (jstack == 0) if (jstack == 0)
return; 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]; l = istack[jstack - 1];
jstack -= 2; jstack -= 2;
} else { } 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). // element a. Also rearrange so that a(l) < a(l+1) < a(ir).
tmp_a = arr[k]; tmp_a = arr[k];
arr[k] = arr[l + 1]; arr[k] = arr[l + 1];
@ -100,8 +97,7 @@ void quicksort( std::vector<T> &x )
} }
} }
template <class T1, class T2> 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) if (x.size() <= 1u)
return; return;
T1 *arr = &x[0]; T1 *arr = &x[0];
@ -137,11 +133,13 @@ void quicksort( std::vector<T1> &x, std::vector<T2> &y )
} }
if (jstack == 0) if (jstack == 0)
return; 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]; l = istack[jstack - 1];
jstack -= 2; jstack -= 2;
} else { } 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). // element a. Also rearrange so that a(l) ? a(l+1) ? a(ir).
tmp_a = arr[k]; tmp_a = arr[k];
arr[k] = arr[l + 1]; arr[k] = arr[l + 1];
@ -209,9 +207,7 @@ void quicksort( std::vector<T1> &x, std::vector<T2> &y )
} }
} }
} }
template<class T> template <class T> void unique(std::vector<T> &x) {
void unique( std::vector<T> &x )
{
if (x.size() <= 1) if (x.size() <= 1)
return; return;
// First perform a quicksort // First perform a quicksort
@ -228,7 +224,6 @@ void unique( std::vector<T> &x )
x.resize(pos); x.resize(pos);
} }
} // namespace Utilities
}
#endif #endif

View File

@ -24,7 +24,6 @@
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
/*! \defgroup Macros Set of utility macro functions /*! \defgroup Macros Set of utility macro functions
* \details These functions are a list of C++ macros that are used * \details These functions are a list of C++ macros that are used
* for common operations, including checking for errors. * for common operations, including checking for errors.
@ -32,7 +31,6 @@
* @{ * @{
*/ */
/*! \def NULL_STATEMENT /*! \def NULL_STATEMENT
* \brief A null statement * \brief A null statement
* \details A statement that does nothing, for insure++ make it something * \details A statement that does nothing, for insure++ make it something
@ -50,7 +48,6 @@
#endif #endif
#endif #endif
/*! \def NULL_USE(variable) /*! \def NULL_USE(variable)
* \brief A null use of a variable * \brief A null use of a variable
* \details A null use of a variable, use to avoid GNU compiler warnings about unused variables. * \details A null use of a variable, use to avoid GNU compiler warnings about unused variables.
@ -66,7 +63,6 @@
} while (0) } while (0)
#endif #endif
/*! \def ERROR(MSG) /*! \def ERROR(MSG)
* \brief Throw error * \brief Throw error
* \details Throw an error exception from within any C++ source code. The * \details Throw an error exception from within any C++ source code. The
@ -79,7 +75,6 @@
::Utilities::abort(MSG, __FILE__, __LINE__); \ ::Utilities::abort(MSG, __FILE__, __LINE__); \
} while (0) } while (0)
/*! \def WARNING(MSG) /*! \def WARNING(MSG)
* \brief Print a warning * \brief Print a warning
* \details Print a warning without exit. Print file and line number of the warning. * \details Print a warning without exit. Print file and line number of the warning.
@ -93,7 +88,6 @@
tboxos.str().c_str(), __FILE__, __LINE__); \ tboxos.str().c_str(), __FILE__, __LINE__); \
} while (0) } while (0)
/*! \def ASSERT(EXP) /*! \def ASSERT(EXP)
* \brief Assert error * \brief Assert error
* \details Throw an error exception from within any C++ source code if the * \details Throw an error exception from within any C++ source code if the
@ -111,7 +105,6 @@
} \ } \
} while (0) } while (0)
/*! \def INSIST(EXP,MSG) /*! \def INSIST(EXP,MSG)
* \brief Insist error * \brief Insist error
* \details Throw an error exception from within any C++ source code if the * \details Throw an error exception from within any C++ source code if the
@ -121,7 +114,8 @@
* \param EXP Expression to evaluate * \param EXP Expression to evaluate
* \param MSG Debug message to print * \param MSG Debug message to print
*/ */
#define INSIST(EXP,MSG) do { \ #define INSIST(EXP, MSG) \
do { \
if (!(EXP)) { \ if (!(EXP)) { \
std::stringstream tboxos; \ std::stringstream tboxos; \
tboxos << "Failed insist: " << #EXP << std::endl; \ tboxos << "Failed insist: " << #EXP << std::endl; \
@ -130,7 +124,6 @@
} \ } \
} while (0) } while (0)
/** /**
* Macro for use when assertions are to be included * Macro for use when assertions are to be included
* only when debugging. * only when debugging.
@ -148,7 +141,6 @@
#define CHECK_ASSERT(EXP) #define CHECK_ASSERT(EXP)
#endif #endif
/*! \def DISABLE_WARNINGS /*! \def DISABLE_WARNINGS
* \brief Reenable warnings * \brief Reenable warnings
* \details This will re-enable warnings after a call to DIASABLE_WARNINGS * \details This will re-enable warnings after a call to DIASABLE_WARNINGS
@ -190,9 +182,6 @@
#endif #endif
// clang-format on // clang-format on
/*! @} */ /*! @} */
#endif #endif

View File

@ -3,8 +3,8 @@ This class implements support for halo widths larger than 1
*/ */
#include "common/WideHalo.h" #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 Lock = false; // unlock the communicator
//...................................................................................... //......................................................................................
@ -62,123 +62,283 @@ ScaLBLWideHalo_Communicator::ScaLBLWideHalo_Communicator(std::shared_ptr <Domain
/* Fill in communications patterns for the lists */ /* Fill in communications patterns for the lists */
/* Send lists */ /* Send lists */
sendCount_x =getHaloBlock(width,2*width,width,Nyh-width,width,Nzh-width,dvcSendList_x); sendCount_x = getHaloBlock(width, 2 * width, width, Nyh - width, width,
sendCount_X =getHaloBlock(Nxh-2*width,Nxh-width,width,Nyh-width,width,Nzh-width,dvcSendList_X); Nzh - width, dvcSendList_x);
sendCount_y =getHaloBlock(width,Nxh-width,width,2*width,width,Nzh-width,dvcSendList_y); sendCount_X = getHaloBlock(Nxh - 2 * width, Nxh - width, width, Nyh - width,
sendCount_Y =getHaloBlock(width,Nxh-width,Nyh-2*width,Nyh-width,width,Nzh-width,dvcSendList_Y); width, Nzh - width, dvcSendList_X);
sendCount_z =getHaloBlock(width,Nxh-width,width,Nyh-width,width,2*width,dvcSendList_z); sendCount_y = getHaloBlock(width, Nxh - width, width, 2 * width, width,
sendCount_Z =getHaloBlock(width,Nxh-width,width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_Z); 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 // xy
sendCount_xy =getHaloBlock(width,2*width,width,2*width,width,Nzh-width,dvcSendList_xy); sendCount_xy = getHaloBlock(width, 2 * width, width, 2 * width, width,
sendCount_xY =getHaloBlock(width,2*width,Nyh-2*width,Nyh-width,width,Nzh-width,dvcSendList_xY); Nzh - width, dvcSendList_xy);
sendCount_Xy =getHaloBlock(Nxh-2*width,Nxh-width,width,2*width,width,Nzh-width,dvcSendList_Xy); sendCount_xY = getHaloBlock(width, 2 * width, Nyh - 2 * width, Nyh - width,
sendCount_XY =getHaloBlock(Nxh-2*width,Nxh-width,Nyh-2*width,Nyh-width,width,Nzh-width,dvcSendList_XY); 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 // xz
sendCount_xz =getHaloBlock(width,2*width,width,Nyh-width,width,2*width,dvcSendList_xz); sendCount_xz = getHaloBlock(width, 2 * width, width, Nyh - width, width,
sendCount_xZ =getHaloBlock(width,2*width,width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_xZ); 2 * width, dvcSendList_xz);
sendCount_Xz =getHaloBlock(Nxh-2*width,Nxh-width,width,Nyh-width,width,2*width,dvcSendList_Xz); sendCount_xZ = getHaloBlock(width, 2 * width, width, Nyh - width,
sendCount_XZ =getHaloBlock(Nxh-2*width,Nxh-width,width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_XZ); 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 // yz
sendCount_yz =getHaloBlock(width,Nxh-width,width,2*width,width,2*width,dvcSendList_yz); sendCount_yz = getHaloBlock(width, Nxh - width, width, 2 * width, width,
sendCount_yZ =getHaloBlock(width,Nxh-width,width,2*width,Nzh-2*width,Nzh-width,dvcSendList_yZ); 2 * 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, width, 2 * width,
sendCount_YZ =getHaloBlock(width,Nxh-width,Nyh-2*width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_YZ); 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 // xyz
sendCount_xyz =getHaloBlock(width,2*width,width,2*width,width,2*width,dvcSendList_xyz); sendCount_xyz = getHaloBlock(width, 2 * width, width, 2 * width, width,
sendCount_xyZ =getHaloBlock(width,2*width,width,2*width,Nzh-2*width,Nzh-width,dvcSendList_xyZ); 2 * 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, width, 2 * width,
sendCount_xYZ =getHaloBlock(width,2*width,Nyh-2*width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_xYZ); 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(width, 2 * width, Nyh - 2 * width, Nyh - width,
sendCount_XyZ =getHaloBlock(Nxh-2*width,Nxh-width,width,2*width,Nzh-2*width,Nzh-width,dvcSendList_XyZ); width, 2 * width, dvcSendList_xYz);
sendCount_XYz =getHaloBlock(Nxh-2*width,Nxh-width,Nyh-2*width,Nyh-width,width,2*width,dvcSendList_XYz); sendCount_xYZ = getHaloBlock(width, 2 * width, Nyh - 2 * width, Nyh - width,
sendCount_XYZ =getHaloBlock(Nxh-2*width,Nxh-width,Nyh-2*width,Nyh-width,Nzh-2*width,Nzh-width,dvcSendList_XYZ); 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 */ /* Recv lists */
recvCount_x =getHaloBlock(0,width,width,Nyh-width,width,Nzh-width,dvcRecvList_x); recvCount_x = getHaloBlock(0, width, width, Nyh - width, width, Nzh - width,
recvCount_X =getHaloBlock(Nxh-width,Nxh,width,Nyh-width,width,Nzh-width,dvcRecvList_X); dvcRecvList_x);
recvCount_y =getHaloBlock(width,Nxh-width,0,width,width,Nzh-width,dvcRecvList_y); recvCount_X = getHaloBlock(Nxh - width, Nxh, width, Nyh - width, width,
recvCount_Y =getHaloBlock(width,Nxh-width,Nyh-width,Nyh,width,Nzh-width,dvcRecvList_Y); Nzh - width, dvcRecvList_X);
recvCount_z =getHaloBlock(width,Nxh-width,width,Nyh-width,0,width,dvcRecvList_z); recvCount_y = getHaloBlock(width, Nxh - width, 0, width, width, Nzh - width,
recvCount_Z =getHaloBlock(width,Nxh-width,width,Nyh-width,Nzh-width,Nzh,dvcRecvList_Z); 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 //xy
recvCount_xy =getHaloBlock(0,width,0,width,width,Nzh-width,dvcRecvList_xy); recvCount_xy =
recvCount_xY =getHaloBlock(0,width,Nyh-width,Nyh,width,Nzh-width,dvcRecvList_xY); getHaloBlock(0, width, 0, width, width, Nzh - width, dvcRecvList_xy);
recvCount_Xy =getHaloBlock(Nxh-width,Nxh,0,width,width,Nzh-width,dvcRecvList_Xy); recvCount_xY = getHaloBlock(0, width, Nyh - width, Nyh, width, Nzh - width,
recvCount_XY =getHaloBlock(Nxh-width,Nxh,Nyh-width,Nyh,width,Nzh-width,dvcRecvList_XY); 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 //xz
recvCount_xz =getHaloBlock(0,width,width,Nyh-width,0,width,dvcRecvList_xz); recvCount_xz =
recvCount_xZ =getHaloBlock(0,width,width,Nyh-width,Nzh-width,Nzh,dvcRecvList_xZ); getHaloBlock(0, width, width, Nyh - width, 0, width, dvcRecvList_xz);
recvCount_Xz =getHaloBlock(Nxh-width,Nxh,width,Nyh-width,0,width,dvcRecvList_Xz); recvCount_xZ = getHaloBlock(0, width, width, Nyh - width, Nzh - width, Nzh,
recvCount_XZ =getHaloBlock(Nxh-width,Nxh,width,Nyh-width,Nzh-width,Nzh,dvcRecvList_XZ); 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 //yz
recvCount_yz =getHaloBlock(width,Nxh-width,0,width,0,width,dvcRecvList_yz); recvCount_yz =
recvCount_yZ =getHaloBlock(width,Nxh-width,0,width,Nzh-width,Nzh,dvcRecvList_yZ); getHaloBlock(width, Nxh - width, 0, width, 0, width, dvcRecvList_yz);
recvCount_Yz =getHaloBlock(width,Nxh-width,Nyh-width,Nyh,0,width,dvcRecvList_Yz); recvCount_yZ = getHaloBlock(width, Nxh - width, 0, width, Nzh - width, Nzh,
recvCount_YZ =getHaloBlock(width,Nxh-width,Nyh-width,Nyh,Nzh-width,Nzh,dvcRecvList_YZ); 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 //xyz
recvCount_xyz = getHaloBlock(0, width, 0, width, 0, width, dvcRecvList_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 =
recvCount_xYz =getHaloBlock(0,width,Nyh-width,Nyh,0,width,dvcRecvList_xYz); getHaloBlock(0, width, 0, width, Nzh - width, Nzh, dvcRecvList_xyZ);
recvCount_xYZ =getHaloBlock(0,width,Nyh-width,Nyh,Nzh-width,Nzh,dvcRecvList_xYZ); recvCount_xYz =
recvCount_Xyz =getHaloBlock(Nxh-width,Nxh,0,width,0,width,dvcRecvList_Xyz); getHaloBlock(0, width, Nyh - width, Nyh, 0, width, dvcRecvList_xYz);
recvCount_XyZ =getHaloBlock(Nxh-width,Nxh,0,width,Nzh-width,Nzh,dvcRecvList_XyZ); recvCount_xYZ = getHaloBlock(0, width, Nyh - width, Nyh, Nzh - width, Nzh,
recvCount_XYz =getHaloBlock(Nxh-width,Nxh,Nyh-width,Nyh,0,width,dvcRecvList_XYz); dvcRecvList_xYZ);
recvCount_XYZ =getHaloBlock(Nxh-width,Nxh,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,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_X, sendCount_X*sizeof(double)); // Allocate device memory sendCount_x *
ScaLBL_AllocateZeroCopy((void **) &sendbuf_y, sendCount_y*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Y, sendCount_Y*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&sendbuf_X,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_z, sendCount_z*sizeof(double)); // Allocate device memory sendCount_X *
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Z, sendCount_Z*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xy, sendCount_xy*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&sendbuf_y,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xY, sendCount_xY*sizeof(double)); // Allocate device memory sendCount_y *
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xy, sendCount_Xy*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XY, sendCount_XY*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&sendbuf_Y,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xz, sendCount_xz*sizeof(double)); // Allocate device memory sendCount_Y *
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xZ, sendCount_xZ*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xz, sendCount_Xz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&sendbuf_z,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XZ, sendCount_XZ*sizeof(double)); // Allocate device memory sendCount_z *
ScaLBL_AllocateZeroCopy((void **) &sendbuf_yz, sendCount_yz*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_yZ, sendCount_yZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&sendbuf_Z,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Yz, sendCount_Yz*sizeof(double)); // Allocate device memory sendCount_Z *
ScaLBL_AllocateZeroCopy((void **) &sendbuf_YZ, sendCount_YZ*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xyz, sendCount_xyz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&sendbuf_xy,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xYz, sendCount_xYz*sizeof(double)); // Allocate device memory sendCount_xy *
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xyz, sendCount_Xyz*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XYz, sendCount_XYz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&sendbuf_xY,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xyZ, sendCount_xyZ*sizeof(double)); // Allocate device memory sendCount_xY *
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xYZ, sendCount_xYZ*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XyZ, sendCount_XyZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&sendbuf_Xy,
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XYZ, sendCount_XYZ*sizeof(double)); // Allocate device memory 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,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_X, recvCount_X*sizeof(double)); // Allocate device memory recvCount_x *
ScaLBL_AllocateZeroCopy((void **) &recvbuf_y, recvCount_y*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Y, recvCount_Y*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&recvbuf_X,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_z, recvCount_z*sizeof(double)); // Allocate device memory recvCount_X *
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Z, recvCount_Z*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xy, recvCount_xy*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&recvbuf_y,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xY, recvCount_xY*sizeof(double)); // Allocate device memory recvCount_y *
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xy, recvCount_Xy*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XY, recvCount_XY*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&recvbuf_Y,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xz, recvCount_xz*sizeof(double)); // Allocate device memory recvCount_Y *
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xZ, recvCount_xZ*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xz, recvCount_Xz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&recvbuf_z,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XZ, recvCount_XZ*sizeof(double)); // Allocate device memory recvCount_z *
ScaLBL_AllocateZeroCopy((void **) &recvbuf_yz, recvCount_yz*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_yZ, recvCount_yZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&recvbuf_Z,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Yz, recvCount_Yz*sizeof(double)); // Allocate device memory recvCount_Z *
ScaLBL_AllocateZeroCopy((void **) &recvbuf_YZ, recvCount_YZ*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xyz, recvCount_xyz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&recvbuf_xy,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xYz, recvCount_xYz*sizeof(double)); // Allocate device memory recvCount_xy *
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xyz, recvCount_Xyz*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XYz, recvCount_XYz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&recvbuf_xY,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xyZ, recvCount_xyZ*sizeof(double)); // Allocate device memory recvCount_xY *
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xYZ, recvCount_xYZ*sizeof(double)); // Allocate device memory sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XyZ, recvCount_XyZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **)&recvbuf_Xy,
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XYZ, recvCount_XYZ*sizeof(double)); // Allocate device memory 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 */ /* Set up a map to the halo width=1 data structure */
for (k = width; k < Nzh - width; k++) { 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) { void ScaLBLWideHalo_Communicator::Send(double *data) {
//................................................................................... //...................................................................................
if (Lock == true) { if (Lock == true) {
ERROR("ScaLBL Error (SendHalo): ScaLBLWideHalo_Communicator is locked -- did you forget to match Send/Recv calls?"); ERROR("ScaLBL Error (SendHalo): ScaLBLWideHalo_Communicator is locked "
} "-- did you forget to match Send/Recv calls?");
else{ } else {
Lock = true; Lock = true;
} }
ScaLBL_DeviceBarrier(); ScaLBL_DeviceBarrier();
@ -234,67 +393,115 @@ void ScaLBLWideHalo_Communicator::Send(double *data){
//................................................................................... //...................................................................................
// Send / Recv all the phase indcator field values // Send / Recv all the phase indcator field values
//................................................................................... //...................................................................................
req1[0] = MPI_COMM_SCALBL.Isend(sendbuf_x,sendCount_x,rank_x,sendtag+0); req1[0] =
req2[0] = MPI_COMM_SCALBL.Irecv(recvbuf_X,recvCount_X,rank_X,recvtag+0); MPI_COMM_SCALBL.Isend(sendbuf_x, sendCount_x, rank_x, sendtag + 0);
req1[1] = MPI_COMM_SCALBL.Isend(sendbuf_X,sendCount_X,rank_X,sendtag+1); req2[0] =
req2[1] = MPI_COMM_SCALBL.Irecv(recvbuf_x,recvCount_x,rank_x,recvtag+1); MPI_COMM_SCALBL.Irecv(recvbuf_X, recvCount_X, rank_X, recvtag + 0);
req1[2] = MPI_COMM_SCALBL.Isend(sendbuf_y,sendCount_y,rank_y,sendtag+2); req1[1] =
req2[2] = MPI_COMM_SCALBL.Irecv(recvbuf_Y,recvCount_Y,rank_Y,recvtag+2); MPI_COMM_SCALBL.Isend(sendbuf_X, sendCount_X, rank_X, sendtag + 1);
req1[3] = MPI_COMM_SCALBL.Isend(sendbuf_Y,sendCount_Y,rank_Y,sendtag+3); req2[1] =
req2[3] = MPI_COMM_SCALBL.Irecv(recvbuf_y,recvCount_y,rank_y,recvtag+3); MPI_COMM_SCALBL.Irecv(recvbuf_x, recvCount_x, rank_x, recvtag + 1);
req1[4] = MPI_COMM_SCALBL.Isend(sendbuf_z,sendCount_z,rank_z,sendtag+4); req1[2] =
req2[4] = MPI_COMM_SCALBL.Irecv(recvbuf_Z,recvCount_Z,rank_Z,recvtag+4); MPI_COMM_SCALBL.Isend(sendbuf_y, sendCount_y, rank_y, sendtag + 2);
req1[5] = MPI_COMM_SCALBL.Isend(sendbuf_Z,sendCount_Z,rank_Z,sendtag+5); req2[2] =
req2[5] = MPI_COMM_SCALBL.Irecv(recvbuf_z,recvCount_z,rank_z,recvtag+5); MPI_COMM_SCALBL.Irecv(recvbuf_Y, recvCount_Y, rank_Y, recvtag + 2);
req1[6] = MPI_COMM_SCALBL.Isend(sendbuf_xy,sendCount_xy,rank_xy,sendtag+6); req1[3] =
req2[6] = MPI_COMM_SCALBL.Irecv(recvbuf_XY,recvCount_XY,rank_XY,recvtag+6); MPI_COMM_SCALBL.Isend(sendbuf_Y, sendCount_Y, rank_Y, sendtag + 3);
req1[7] = MPI_COMM_SCALBL.Isend(sendbuf_XY,sendCount_XY,rank_XY,sendtag+7); req2[3] =
req2[7] = MPI_COMM_SCALBL.Irecv(recvbuf_xy,recvCount_xy,rank_xy,recvtag+7); MPI_COMM_SCALBL.Irecv(recvbuf_y, recvCount_y, rank_y, recvtag + 3);
req1[8] = MPI_COMM_SCALBL.Isend(sendbuf_Xy,sendCount_Xy,rank_Xy,sendtag+8); req1[4] =
req2[8] = MPI_COMM_SCALBL.Irecv(recvbuf_xY,recvCount_xY,rank_xY,recvtag+8); MPI_COMM_SCALBL.Isend(sendbuf_z, sendCount_z, rank_z, sendtag + 4);
req1[9] = MPI_COMM_SCALBL.Isend(sendbuf_xY,sendCount_xY,rank_xY,sendtag+9); req2[4] =
req2[9] = MPI_COMM_SCALBL.Irecv(recvbuf_Xy,recvCount_Xy,rank_Xy,recvtag+9); MPI_COMM_SCALBL.Irecv(recvbuf_Z, recvCount_Z, rank_Z, recvtag + 4);
req1[10] = MPI_COMM_SCALBL.Isend(sendbuf_xz,sendCount_xz,rank_xz,sendtag+10); req1[5] =
req2[10] = MPI_COMM_SCALBL.Irecv(recvbuf_XZ,recvCount_XZ,rank_XZ,recvtag+10); MPI_COMM_SCALBL.Isend(sendbuf_Z, sendCount_Z, rank_Z, sendtag + 5);
req1[11] = MPI_COMM_SCALBL.Isend(sendbuf_XZ,sendCount_XZ,rank_XZ,sendtag+11); req2[5] =
req2[11] = MPI_COMM_SCALBL.Irecv(recvbuf_xz,recvCount_xz,rank_xz,recvtag+11); MPI_COMM_SCALBL.Irecv(recvbuf_z, recvCount_z, rank_z, recvtag + 5);
req1[12] = MPI_COMM_SCALBL.Isend(sendbuf_Xz,sendCount_Xz,rank_Xz,sendtag+12); req1[6] =
req2[12] = MPI_COMM_SCALBL.Irecv(recvbuf_xZ,recvCount_xZ,rank_xZ,recvtag+12); MPI_COMM_SCALBL.Isend(sendbuf_xy, sendCount_xy, rank_xy, sendtag + 6);
req1[13] = MPI_COMM_SCALBL.Isend(sendbuf_xZ,sendCount_xZ,rank_xZ,sendtag+13); req2[6] =
req2[13] = MPI_COMM_SCALBL.Irecv(recvbuf_Xz,recvCount_Xz,rank_Xz,recvtag+13); MPI_COMM_SCALBL.Irecv(recvbuf_XY, recvCount_XY, rank_XY, recvtag + 6);
req1[14] = MPI_COMM_SCALBL.Isend(sendbuf_yz,sendCount_yz,rank_yz,sendtag+14); req1[7] =
req2[14] = MPI_COMM_SCALBL.Irecv(recvbuf_YZ,recvCount_YZ,rank_YZ,recvtag+14); MPI_COMM_SCALBL.Isend(sendbuf_XY, sendCount_XY, rank_XY, sendtag + 7);
req1[15] = MPI_COMM_SCALBL.Isend(sendbuf_YZ,sendCount_YZ,rank_YZ,sendtag+15); req2[7] =
req2[15] = MPI_COMM_SCALBL.Irecv(recvbuf_yz,recvCount_yz,rank_yz,recvtag+15); MPI_COMM_SCALBL.Irecv(recvbuf_xy, recvCount_xy, rank_xy, recvtag + 7);
req1[16] = MPI_COMM_SCALBL.Isend(sendbuf_Yz,sendCount_Yz,rank_Yz,sendtag+16); req1[8] =
req2[16] = MPI_COMM_SCALBL.Irecv(recvbuf_yZ,recvCount_yZ,rank_yZ,recvtag+16); MPI_COMM_SCALBL.Isend(sendbuf_Xy, sendCount_Xy, rank_Xy, sendtag + 8);
req1[17] = MPI_COMM_SCALBL.Isend(sendbuf_yZ,sendCount_yZ,rank_yZ,sendtag+17); req2[8] =
req2[17] = MPI_COMM_SCALBL.Irecv(recvbuf_Yz,recvCount_Yz,rank_Yz,recvtag+17); 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 */ /* Corners */
req1[18] = MPI_COMM_SCALBL.Isend(sendbuf_xyz,sendCount_xyz,rank_xyz,sendtag+18); req1[18] = MPI_COMM_SCALBL.Isend(sendbuf_xyz, sendCount_xyz, rank_xyz,
req2[18] = MPI_COMM_SCALBL.Irecv(recvbuf_XYZ,recvCount_XYZ,rank_XYZ,recvtag+18); sendtag + 18);
req1[19] = MPI_COMM_SCALBL.Isend(sendbuf_XYz,sendCount_XYz,rank_XYz,sendtag+19); req2[18] = MPI_COMM_SCALBL.Irecv(recvbuf_XYZ, recvCount_XYZ, rank_XYZ,
req2[19] = MPI_COMM_SCALBL.Irecv(recvbuf_xyZ,recvCount_xyZ,rank_xyZ,recvtag+19); recvtag + 18);
req1[20] = MPI_COMM_SCALBL.Isend(sendbuf_Xyz,sendCount_Xyz,rank_Xyz,sendtag+20); req1[19] = MPI_COMM_SCALBL.Isend(sendbuf_XYz, sendCount_XYz, rank_XYz,
req2[20] = MPI_COMM_SCALBL.Irecv(recvbuf_xYZ,recvCount_xYZ,rank_xYZ,recvtag+20); sendtag + 19);
req1[21] = MPI_COMM_SCALBL.Isend(sendbuf_xYz,sendCount_xYz,rank_xYz,sendtag+21); req2[19] = MPI_COMM_SCALBL.Irecv(recvbuf_xyZ, recvCount_xyZ, rank_xyZ,
req2[21] = MPI_COMM_SCALBL.Irecv(recvbuf_XyZ,recvCount_XyZ,rank_XyZ,recvtag+21); recvtag + 19);
req1[22] = MPI_COMM_SCALBL.Isend(sendbuf_xyZ,sendCount_xyZ,rank_xyZ,sendtag+22); req1[20] = MPI_COMM_SCALBL.Isend(sendbuf_Xyz, sendCount_Xyz, rank_Xyz,
req2[22] = MPI_COMM_SCALBL.Irecv(recvbuf_XYz,recvCount_XYz,rank_XYz,recvtag+22); sendtag + 20);
req1[23] = MPI_COMM_SCALBL.Isend(sendbuf_XYZ,sendCount_XYZ,rank_XYZ,sendtag+23); req2[20] = MPI_COMM_SCALBL.Irecv(recvbuf_xYZ, recvCount_xYZ, rank_xYZ,
req2[23] = MPI_COMM_SCALBL.Irecv(recvbuf_xyz,recvCount_xyz,rank_xyz,recvtag+23); recvtag + 20);
req1[24] = MPI_COMM_SCALBL.Isend(sendbuf_XyZ,sendCount_XyZ,rank_XyZ,sendtag+24); req1[21] = MPI_COMM_SCALBL.Isend(sendbuf_xYz, sendCount_xYz, rank_xYz,
req2[24] = MPI_COMM_SCALBL.Irecv(recvbuf_xYz,recvCount_xYz,rank_xYz,recvtag+24); sendtag + 21);
req1[25] = MPI_COMM_SCALBL.Isend(sendbuf_xYZ,sendCount_xYZ,rank_xYZ,sendtag+25); req2[21] = MPI_COMM_SCALBL.Irecv(recvbuf_XyZ, recvCount_XyZ, rank_XyZ,
req2[25] = MPI_COMM_SCALBL.Irecv(recvbuf_Xyz,recvCount_Xyz,rank_Xyz,recvtag+25); 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) { void ScaLBLWideHalo_Communicator::Recv(double *data) {
//................................................................................... //...................................................................................
@ -335,6 +542,4 @@ void ScaLBLWideHalo_Communicator::Recv(double *data){
//................................................................................... //...................................................................................
Lock = false; // unlock the communicator after communications complete Lock = false; // unlock the communicator after communications complete
//................................................................................... //...................................................................................
} }

View File

@ -23,14 +23,20 @@ public:
// Set up for D3Q19 distributions -- all 27 neighbors are needed // Set up for D3Q19 distributions -- all 27 neighbors are needed
//...................................................................................... //......................................................................................
// Buffers to store data sent and recieved by this MPI process // 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_x, *sendbuf_y, *sendbuf_z, *sendbuf_X, *sendbuf_Y,
double *sendbuf_xy, *sendbuf_yz, *sendbuf_xz, *sendbuf_Xy, *sendbuf_Yz, *sendbuf_xZ; *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_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 *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_x, *recvbuf_y, *recvbuf_z, *recvbuf_X, *recvbuf_Y,
double *recvbuf_xy, *recvbuf_yz, *recvbuf_xz, *recvbuf_Xy, *recvbuf_Yz, *recvbuf_xZ; *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_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;
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(); void PrintDebug();
private: 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) // only one set of Send requests can be active at any time (per instance)
int i, j, k, n; int i, j, k, n;
int iproc, jproc, kproc; int iproc, jproc, kproc;
@ -68,33 +75,46 @@ private:
int rank_xyZ, rank_XyZ, rank_xYZ, rank_XYZ; int rank_xyZ, rank_XyZ, rank_xYZ, rank_XYZ;
//...................................................................................... //......................................................................................
//...................................................................................... //......................................................................................
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y, sendCount_Z; int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y,
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz, sendCount_xZ; 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_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 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_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y,
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz, recvCount_xZ; 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_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;
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 // Send buffers that reside on the compute device
int *dvcSendList_x, *dvcSendList_y, *dvcSendList_z, *dvcSendList_X, *dvcSendList_Y, *dvcSendList_Z; int *dvcSendList_x, *dvcSendList_y, *dvcSendList_z, *dvcSendList_X,
int *dvcSendList_xy, *dvcSendList_yz, *dvcSendList_xz, *dvcSendList_Xy, *dvcSendList_Yz, *dvcSendList_xZ; *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_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;
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 // Recieve buffers that reside on the compute device
int *dvcRecvList_x, *dvcRecvList_y, *dvcRecvList_z, *dvcRecvList_X, *dvcRecvList_Y, *dvcRecvList_Z; int *dvcRecvList_x, *dvcRecvList_y, *dvcRecvList_z, *dvcRecvList_X,
int *dvcRecvList_xy, *dvcRecvList_yz, *dvcRecvList_xz, *dvcRecvList_Xy, *dvcRecvList_Yz, *dvcRecvList_xZ; *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_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;
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 count = 0;
int *List; int *List;
List = new int[(imax - imin) * (jmax - jmin) * (kmax - kmin)]; List = new int[(imax - imin) * (jmax - jmin) * (kmax - kmin)];
@ -106,10 +126,10 @@ private:
} }
} }
size_t numbytes = count * sizeof(int); 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); ScaLBL_CopyToZeroCopy(dvcList, List, numbytes);
return count; return count;
} }
}; };
#endif #endif

View File

@ -14,11 +14,14 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>. 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){ 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 // conserved momemnts
double rho, ux, uy, uz, uu; double rho, ux, uy, uz, uu;
// non-conserved moments // 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++) { for (int n = start; n < finish; n++) {
// q=0 // q=0
@ -42,7 +45,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_BGK(double *dist, int start, int finish, int
f17 = dist[18 * Np + n]; f17 = dist[18 * Np + n];
f18 = dist[17 * 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; ux = f1 - f2 + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14;
uy = f3 - f4 + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18; uy = f3 - f4 + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18;
uz = f5 - f6 + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18; uz = f5 - f6 + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18;
@ -52,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); dist[n] = f0 * (1.0 - rlx) + rlx * 0.3333333333333333 * (1.0 - uu);
// q = 1 // 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 // 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 // q = 3
dist[3*Np+n] = f3*(1.0-rlx) + dist[3 * Np + n] =
rlx*0.05555555555555555*(rho + 3.0*uy + 4.5*uy*uy - uu) + 0.16666666*Fy; f3 * (1.0 - rlx) +
rlx * 0.05555555555555555 * (rho + 3.0 * uy + 4.5 * uy * uy - uu) +
0.16666666 * Fy;
// q = 4 // q = 4
dist[4*Np+n] = f4*(1.0-rlx) + dist[4 * Np + n] =
rlx*0.05555555555555555*(rho - 3.0*uy + 4.5*uy*uy - uu)- 0.16666666*Fy; f4 * (1.0 - rlx) +
rlx * 0.05555555555555555 * (rho - 3.0 * uy + 4.5 * uy * uy - uu) -
0.16666666 * Fy;
// q = 5 // q = 5
dist[5*Np+n] = f5*(1.0-rlx) + dist[5 * Np + n] =
rlx*0.05555555555555555*(rho + 3.0*uz + 4.5*uz*uz - uu) + 0.16666666*Fz; f5 * (1.0 - rlx) +
rlx * 0.05555555555555555 * (rho + 3.0 * uz + 4.5 * uz * uz - uu) +
0.16666666 * Fz;
// q = 6 // q = 6
dist[6*Np+n] = f6*(1.0-rlx) + dist[6 * Np + n] =
rlx*0.05555555555555555*(rho - 3.0*uz + 4.5*uz*uz - uu) - 0.16666666*Fz; f6 * (1.0 - rlx) +
rlx * 0.05555555555555555 * (rho - 3.0 * uz + 4.5 * uz * uz - uu) -
0.16666666 * Fz;
// q = 7 // q = 7
dist[7*Np+n] = f7*(1.0-rlx) + dist[7 * Np + n] =
rlx*0.02777777777777778*(rho + 3.0*(ux+uy) + 4.5*(ux+uy)*(ux+uy) - uu) + 0.08333333333*(Fx+Fy); 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 // q = 8
dist[8*Np+n] = f8*(1.0-rlx) + dist[8 * Np + n] =
rlx*0.02777777777777778*(rho - 3.0*(ux+uy) + 4.5*(ux+uy)*(ux+uy) - uu) - 0.08333333333*(Fx+Fy); 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 // q = 9
dist[9*Np+n] = f9*(1.0-rlx) + dist[9 * Np + n] =
rlx*0.02777777777777778*(rho + 3.0*(ux-uy) + 4.5*(ux-uy)*(ux-uy) - uu) + 0.08333333333*(Fx-Fy); 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 // q = 10
dist[10*Np+n] = f10*(1.0-rlx) + dist[10 * Np + n] =
rlx*0.02777777777777778*(rho - 3.0*(ux-uy) + 4.5*(ux-uy)*(ux-uy) - uu) - 0.08333333333*(Fx-Fy); 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 // q = 11
dist[11*Np+n] = f11*(1.0-rlx) + dist[11 * Np + n] =
rlx*0.02777777777777778*(rho + 3.0*(ux+uz) + 4.5*(ux+uz)*(ux+uz) - uu) + 0.08333333333*(Fx+Fz); 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 // q = 12
dist[12*Np+n] = f12*(1.0-rlx) + dist[12 * Np + n] =
rlx*0.02777777777777778*(rho - 3.0*(ux+uz) + 4.5*(ux+uz)*(ux+uz) - uu) - 0.08333333333*(Fx+Fz); 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 // q = 13
dist[13*Np+n] = f13*(1.0-rlx) + dist[13 * Np + n] =
rlx*0.02777777777777778*(rho + 3.0*(ux-uz) + 4.5*(ux-uz)*(ux-uz) - uu) + 0.08333333333*(Fx-Fz); 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 // q= 14
dist[14*Np+n] = f14*(1.0-rlx) + dist[14 * Np + n] =
rlx*0.02777777777777778*(rho - 3.0*(ux-uz) + 4.5*(ux-uz)*(ux-uz) - uu)- 0.08333333333*(Fx-Fz); 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 // q = 15
dist[15*Np+n] = f15*(1.0-rlx) + dist[15 * Np + n] =
rlx*0.02777777777777778*(rho + 3.0*(uy+uz) + 4.5*(uy+uz)*(uy+uz) - uu) + 0.08333333333*(Fy+Fz); 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 // q = 16
dist[16*Np+n] = f16*(1.0-rlx) + dist[16 * Np + n] =
rlx*0.02777777777777778*(rho - 3.0*(uy+uz) + 4.5*(uy+uz)*(uy+uz) - uu) - 0.08333333333*(Fy+Fz); 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 // q = 17
dist[17*Np+n] = f17*(1.0-rlx) + dist[17 * Np + n] =
rlx*0.02777777777777778*(rho + 3.0*(uy-uz) + 4.5*(uy-uz)*(uy-uz) - uu) + 0.08333333333*(Fy-Fz); 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 // q = 18
dist[18*Np+n] = f18*(1.0-rlx) + dist[18 * Np + n] =
rlx*0.02777777777777778*(rho - 3.0*(uy-uz) + 4.5*(uy-uz)*(uy-uz) - uu) - 0.08333333333*(Fy-Fz); 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 // conserved momemnts
double rho, ux, uy, uz, uu; double rho, ux, uy, uz, uu;
// non-conserved moments // 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,
int nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8,nr9,nr10,nr11,nr12,nr13,nr14,nr15,nr16,nr17,nr18; 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++) { for (int n = start; n < finish; n++) {
@ -208,7 +267,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_BGK(int *neighborList, double *dist, int star
nr18 = neighborList[n + 17 * Np]; nr18 = neighborList[n + 17 * Np];
f18 = dist[nr18]; 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; ux = f1 - f2 + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14;
uy = f3 - f4 + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18; uy = f3 - f4 + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18;
uz = f5 - f6 + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18; uz = f5 - f6 + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18;
@ -218,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); dist[n] = f0 * (1.0 - rlx) + rlx * 0.3333333333333333 * (1.0 - uu);
// q = 1 // 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 // 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 // q = 3
dist[nr4] = f3*(1.0-rlx) + dist[nr4] =
rlx*0.05555555555555555*(rho + 3.0*uy + 4.5*uy*uy - uu) + 0.16666666*Fy; f3 * (1.0 - rlx) +
rlx * 0.05555555555555555 * (rho + 3.0 * uy + 4.5 * uy * uy - uu) +
0.16666666 * Fy;
// q = 4 // q = 4
dist[nr3] = f4*(1.0-rlx) + dist[nr3] =
rlx*0.05555555555555555*(rho - 3.0*uy + 4.5*uy*uy - uu)- 0.16666666*Fy; f4 * (1.0 - rlx) +
rlx * 0.05555555555555555 * (rho - 3.0 * uy + 4.5 * uy * uy - uu) -
0.16666666 * Fy;
// q = 5 // q = 5
dist[nr6] = f5*(1.0-rlx) + dist[nr6] =
rlx*0.05555555555555555*(rho + 3.0*uz + 4.5*uz*uz - uu) + 0.16666666*Fz; f5 * (1.0 - rlx) +
rlx * 0.05555555555555555 * (rho + 3.0 * uz + 4.5 * uz * uz - uu) +
0.16666666 * Fz;
// q = 6 // q = 6
dist[nr5] = f6*(1.0-rlx) + dist[nr5] =
rlx*0.05555555555555555*(rho - 3.0*uz + 4.5*uz*uz - uu) - 0.16666666*Fz; f6 * (1.0 - rlx) +
rlx * 0.05555555555555555 * (rho - 3.0 * uz + 4.5 * uz * uz - uu) -
0.16666666 * Fz;
// q = 7 // q = 7
dist[nr8] = f7*(1.0-rlx) + dist[nr8] =
rlx*0.02777777777777778*(rho + 3.0*(ux+uy) + 4.5*(ux+uy)*(ux+uy) - uu) + 0.08333333333*(Fx+Fy); 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 // q = 8
dist[nr7] = f8*(1.0-rlx) + dist[nr7] =
rlx*0.02777777777777778*(rho - 3.0*(ux+uy) + 4.5*(ux+uy)*(ux+uy) - uu) - 0.08333333333*(Fx+Fy); 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 // q = 9
dist[nr10] = f9*(1.0-rlx) + dist[nr10] =
rlx*0.02777777777777778*(rho + 3.0*(ux-uy) + 4.5*(ux-uy)*(ux-uy) - uu) + 0.08333333333*(Fx-Fy); 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 // q = 10
dist[nr9] = f10*(1.0-rlx) + dist[nr9] =
rlx*0.02777777777777778*(rho - 3.0*(ux-uy) + 4.5*(ux-uy)*(ux-uy) - uu) - 0.08333333333*(Fx-Fy); 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 // q = 11
dist[nr12] = f11*(1.0-rlx) + dist[nr12] =
rlx*0.02777777777777778*(rho + 3.0*(ux+uz) + 4.5*(ux+uz)*(ux+uz) - uu) + 0.08333333333*(Fx+Fz); 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 // q = 12
dist[nr11] = f12*(1.0-rlx) + dist[nr11] =
rlx*0.02777777777777778*(rho - 3.0*(ux+uz) + 4.5*(ux+uz)*(ux+uz) - uu) - 0.08333333333*(Fx+Fz); 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 // q = 13
dist[nr14] = f13*(1.0-rlx) + dist[nr14] =
rlx*0.02777777777777778*(rho + 3.0*(ux-uz) + 4.5*(ux-uz)*(ux-uz) - uu) + 0.08333333333*(Fx-Fz); 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 // q= 14
dist[nr13] = f14*(1.0-rlx) + dist[nr13] =
rlx*0.02777777777777778*(rho - 3.0*(ux-uz) + 4.5*(ux-uz)*(ux-uz) - uu)- 0.08333333333*(Fx-Fz); 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 // q = 15
dist[nr16] = f15*(1.0-rlx) + dist[nr16] =
rlx*0.02777777777777778*(rho + 3.0*(uy+uz) + 4.5*(uy+uz)*(uy+uz) - uu) + 0.08333333333*(Fy+Fz); 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 // q = 16
dist[nr15] = f16*(1.0-rlx) + dist[nr15] =
rlx*0.02777777777777778*(rho - 3.0*(uy+uz) + 4.5*(uy+uz)*(uy+uz) - uu) - 0.08333333333*(Fy+Fz); 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 // q = 17
dist[nr18] = f17*(1.0-rlx) + dist[nr18] =
rlx*0.02777777777777778*(rho + 3.0*(uy-uz) + 4.5*(uy-uz)*(uy-uz) - uu) + 0.08333333333*(Fy-Fz); 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 // q = 18
dist[nr17] = f18*(1.0-rlx) + dist[nr17] =
rlx*0.02777777777777778*(rho - 3.0*(uy-uz) + 4.5*(uy-uz)*(uy-uz) - uu) - 0.08333333333*(Fy-Fz); f18 * (1.0 - rlx) +
rlx * 0.02777777777777778 *
(rho - 3.0 * (uy - uz) + 4.5 * (uy - uz) * (uy - uz) - uu) -
0.08333333333 * (Fy - Fz);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@
*/ */
#include <stdio.h> #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 // Pack distribution q into the send buffer for the listed lattice sites
// dist may be even or odd distributions stored by stream layout // dist may be even or odd distributions stored by stream layout
@ -41,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 // Get the value from the list -- note that n is the index is from the send (non-local) process
n = list[start + idx]; n = list[start + idx];
// unpack the distribution to the proper location // 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]; //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; int n;
for (n = 0; n < Np; n++) { for (n = 0; n < Np; n++) {
f_even[n] = 0.3333333333333333; f_even[n] = 0.3333333333333333;
@ -70,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_even[8 * Np + n] = 0.0277777777777778; //double(100*n)+16.f;
f_odd[8 * Np + n] = 0.0277777777777778; //double(100*n)+17.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; 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; int n;
for (n = 0; n < Np; n++) { for (n = 0; n < Np; n++) {
dist[n] = 0.3333333333333333; dist[n] = 0.3333333333333333;
@ -101,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; int i, j, k, n, nn, N;
// distributions // distributions
double f1, f2, f3, f4, f5, f6, f7, f8, f9; double f1, f2, f3, f4, f5, f6, f7, f8, f9;
@ -135,7 +133,8 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
// Retrieve odd distributions from neighboring nodes (swap convention) // Retrieve odd distributions from neighboring nodes (swap convention)
//........................................................................ //........................................................................
nn = n + 1; // neighbor index (pull 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){ //if (i+1<Nx){
f2 = disteven[N + nn]; // pull neighbor for distribution 2 f2 = disteven[N + nn]; // pull neighbor for distribution 2
if (f2 > 0) { if (f2 > 0) {
@ -145,7 +144,8 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
//} //}
//........................................................................ //........................................................................
nn = n + Nx; // neighbor index (pull convention) 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){ //if (j+1<Ny){
f4 = disteven[2 * N + nn]; // pull neighbor for distribution 4 f4 = disteven[2 * N + nn]; // pull neighbor for distribution 4
if (f4 > 0) { if (f4 > 0) {
@ -155,7 +155,8 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
} }
//........................................................................ //........................................................................
nn = n + Nx * Ny; // neighbor index (pull convention) 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){ //if (k+1<Nz){
f6 = disteven[3 * N + nn]; // pull neighbor for distribution 6 f6 = disteven[3 * N + nn]; // pull neighbor for distribution 6
if (f6 > 0) { if (f6 > 0) {
@ -165,8 +166,10 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
} }
//........................................................................ //........................................................................
nn = n + Nx + 1; // neighbor index (pull convention) nn = n + Nx + 1; // neighbor index (pull convention)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary if (!(i + 1 < Nx))
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary 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)){ //if ((i+1<Nx) && (j+1<Ny)){
f8 = disteven[4 * N + nn]; // pull neighbor for distribution 8 f8 = disteven[4 * N + nn]; // pull neighbor for distribution 8
if (f8 > 0) { if (f8 > 0) {
@ -176,8 +179,10 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
} }
//........................................................................ //........................................................................
nn = n - Nx + 1; // neighbor index (pull convention) nn = n - Nx + 1; // neighbor index (pull convention)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary if (!(i + 1 < Nx))
if (j-1<0) nn += Nx*Ny; // Perioidic BC along the y-boundary 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)){ //if (!(i-1<0) && (j+1<Ny)){
f10 = disteven[5 * N + nn]; // pull neighbor for distribution 9 f10 = disteven[5 * N + nn]; // pull neighbor for distribution 9
if (f10 > 0) { if (f10 > 0) {
@ -187,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) nn = n + Nx * Ny + 1; // neighbor index (pull convention)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary if (!(i + 1 < Nx))
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary 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)){ //if ( !(i-1<0) && !(k-1<0)){
f12 = disteven[6 * N + nn]; // pull distribution 11 f12 = disteven[6 * N + nn]; // pull distribution 11
if (f12 > 0) { if (f12 > 0) {
@ -198,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) nn = n - Nx * Ny + 1; // neighbor index (pull convention)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary if (!(i + 1 < Nx))
if (k-1<0) nn += Nx*Ny*Nz; // Perioidic BC along the z-boundary 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)){ //if (!(i-1<0) && (k+1<Nz)){
f14 = disteven[7 * N + nn]; // pull neighbor for distribution 13 f14 = disteven[7 * N + nn]; // pull neighbor for distribution 13
if (f14 > 0) { if (f14 > 0) {
@ -209,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) nn = n + Nx * Ny + Nx; // neighbor index (pull convention)
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary if (!(j + 1 < Ny))
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary 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)){ //if (!(j-1<0) && !(k-1<0)){
f16 = disteven[8 * N + nn]; // pull neighbor for distribution 15 f16 = disteven[8 * N + nn]; // pull neighbor for distribution 15
if (f16 > 0) { if (f16 > 0) {
@ -220,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) nn = n - Nx * Ny + Nx; // neighbor index (pull convention)
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary if (!(j + 1 < Ny))
if (k-1<0) nn += Nx*Ny*Nz; // Perioidic BC along the z-boundary 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)){ //if (!(j-1<0) && (k+1<Nz)){
f18 = disteven[9 * N + nn]; // pull neighbor for distribution 17 f18 = disteven[9 * N + nn]; // pull neighbor for distribution 17
if (f18 > 0) { if (f18 > 0) {
@ -230,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; int q, n, nn;
double f1, f2; double f1, f2;
for (q = 0; q < 9; q++) { for (q = 0; q < 9; q++) {
@ -252,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,
extern "C" double ScaLBL_D3Q19_Flux_BC_z(double *disteven, double *distodd, double flux, double flux, int Nx, int Ny, int Nz) {
int Nx, int Ny, int Nz){
// Note that this routine assumes the distributions are stored "opposite" // Note that this routine assumes the distributions are stored "opposite"
// odd distributions in disteven and even distributions in distodd. // odd distributions in disteven and even distributions in distodd.
int n, N; int n, N;
@ -295,15 +306,16 @@ extern "C" double ScaLBL_D3Q19_Flux_BC_z(double *disteven, double *distodd, doub
// Determine the outlet flow velocity // 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 += 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+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)); din = sum / (A * (1.0 - flux));
return din; return din;
} }
extern "C" double ScaLBL_D3Q19_AAodd_Flux_BC_z(int *d_neighborList, int *list, double *dist, double flux, extern "C" double ScaLBL_D3Q19_AAodd_Flux_BC_z(int *d_neighborList, int *list,
double area, int count, int Np) double *dist, double flux,
{ double area, int count, int Np) {
int idx, n; int idx, n;
int nread; int nread;
@ -355,15 +367,16 @@ extern "C" double ScaLBL_D3Q19_AAodd_Flux_BC_z(int *d_neighborList, int *list, d
nread = d_neighborList[n + 15 * Np]; nread = d_neighborList[n + 15 * Np];
double f16 = dist[nread]; 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; return sum;
} }
extern "C" double ScaLBL_D3Q19_AAeven_Flux_BC_z(int *list, double *dist, double flux, double area, extern "C" double ScaLBL_D3Q19_AAeven_Flux_BC_z(int *list, double *dist,
int count, int Np) double flux, double area,
{ int count, int Np) {
int idx, n; int idx, n;
// distributions // distributions
double factor = 1.f / (area); double factor = 1.f / (area);
@ -385,14 +398,15 @@ extern "C" double ScaLBL_D3Q19_AAeven_Flux_BC_z(int *list, double *dist, double
double f13 = dist[14 * Np + n]; double f13 = dist[14 * Np + n];
double f16 = dist[15 * Np + n]; double f16 = dist[15 * Np + n];
double f17 = dist[18 * 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; return sum;
} }
extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd,
extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd, double flux, double flux, int Nx, int Ny, int Nz,
int Nx, int Ny, int Nz, int outlet){ int outlet) {
// Note that this routine assumes the distributions are stored "opposite" // Note that this routine assumes the distributions are stored "opposite"
// odd distributions in disteven and even distributions in distodd. // odd distributions in disteven and even distributions in distodd.
int n, N; int n, N;
@ -430,14 +444,15 @@ extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd, doub
//double f16 = disteven[8*N+n]; //double f16 = disteven[8*N+n];
double f18 = disteven[9 * 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)); dout = sum / (A * (1.0 + flux));
return dout; 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++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
@ -455,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++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
@ -473,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 // distributions
double ux, uy, uz, Cyz, Cxz; double ux, uy, uz, Cyz, Cxz;
ux = uy = 0.0; ux = uy = 0.0;
@ -498,7 +515,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_z(int *list, double *dist, doubl
// Determine the inlet flow velocity // Determine the inlet flow velocity
//ux = (f1-f2+f7-f8+f9-f10+f11-f12+f13-f14); //ux = (f1-f2+f7-f8+f9-f10+f11-f12+f13-f14);
//uy = (f3-f4+f7-f8-f9+f10+f15-f16+f17-f18); //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; Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy; Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
@ -517,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 // distributions
double ux, uy, uz, Cyz, Cxz; double ux, uy, uz, Cyz, Cxz;
ux = uy = 0.0; ux = uy = 0.0;
@ -545,7 +564,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_Pressure_BC_Z(int *list, double *dist, doubl
// Determine the outlet flow velocity // Determine the outlet flow velocity
//ux = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14; //ux = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14;
//uy = f3-f4+f7-f8-f9+f10+f15-f16+f17-f18; //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; Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy; Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
@ -565,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 nread;
int nr5, nr11, nr14, nr15, nr18; int nr5, nr11, nr14, nr15, nr18;
// distributions // distributions
@ -627,7 +648,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_z(int *d_neighborList, int *list,
// Determine the inlet flow velocity // Determine the inlet flow velocity
//ux = (f1-f2+f7-f8+f9-f10+f11-f12+f13-f14); //ux = (f1-f2+f7-f8+f9-f10+f11-f12+f13-f14);
//uy = (f3-f4+f7-f8-f9+f10+f15-f16+f17-f18); //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; Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy; Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
@ -646,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 nread;
int nr6, nr12, nr13, nr16, nr17; int nr6, nr12, nr13, nr16, nr17;
// distributions // distributions
@ -682,7 +705,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_Z(int *d_neighborList, int *list,
nread = d_neighborList[n + 14 * Np]; nread = d_neighborList[n + 14 * Np];
double f15 = dist[nread]; double f15 = dist[nread];
nread = d_neighborList[n + Np]; nread = d_neighborList[n + Np];
double f2 = dist[nread]; double f2 = dist[nread];
@ -711,7 +733,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_Z(int *d_neighborList, int *list,
// Determine the inlet flow velocity // Determine the inlet flow velocity
//ux = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14; //ux = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14;
//uy = f3-f4+f7-f8-f9+f10+f15-f16+f17-f18; //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; Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy; Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
@ -732,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, extern "C" void ScaLBL_D3Q19_Velocity_BC_z(double *disteven, double *distodd,
int Nx, int Ny, int Nz) double uz, int Nx, int Ny, int Nz) {
{
int n, N; int n, N;
// distributions // distributions
double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9; double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
@ -774,12 +796,16 @@ extern "C" void ScaLBL_D3Q19_Velocity_BC_z(double *disteven, double *distodd, do
// Determine the outlet flow velocity // Determine the outlet flow velocity
// uz = 1.0 - (f0+f4+f3+f2+f1+f8+f7+f9+f10 + // uz = 1.0 - (f0+f4+f3+f2+f1+f8+f7+f9+f10 +
// 2*(f5+f15+f18+f11+f14))/din; // 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: // Set the unknown distributions:
f6 = f5 + 0.3333333333333333 * din * uz; f6 = f5 + 0.3333333333333333 * din * uz;
f16 = f15 + 0.1666666666666667 * din * uz; f16 = f15 + 0.1666666666666667 * din * uz;
f17 = f16 + f4 - f3 - f15 + f18 + f8 - f7 + f9 - f10; 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; f13 = din * uz + f5 + f15 + f18 + f11 + f14 - f6 - f16 - f17 - f12;
//........Store in "opposite" memory location.......... //........Store in "opposite" memory location..........
@ -792,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, extern "C" void ScaLBL_D3Q19_Velocity_BC_Z(double *disteven, double *distodd,
int Nx, int Ny, int Nz, int outlet) double uz, int Nx, int Ny, int Nz,
{ int outlet) {
int n, N; int n, N;
// distributions // distributions
double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9; double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
@ -829,11 +855,15 @@ extern "C" void ScaLBL_D3Q19_Velocity_BC_Z(double *disteven, double *distodd, do
f16 = disteven[8 * N + n]; f16 = disteven[8 * N + n];
f18 = disteven[9 * 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; //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; f5 = f6 - 0.33333333333333338 * dout * uz;
f15 = f16 - 0.16666666666666678 * dout * uz; f15 = f16 - 0.16666666666666678 * dout * uz;
f18 = f15 - f4 + f3 - f16 + f17 - f8 + f7 - f9 + f10; 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; f14 = -dout * uz + f6 + f16 + f17 + f12 + f13 - f5 - f15 - f18 - f11;
//........Store in "opposite" memory location.......... //........Store in "opposite" memory location..........
distodd[2 * N + n] = f5; distodd[2 * N + n] = f5;
@ -845,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;
int N = Np; int N = Np;
// distributions // distributions
@ -889,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++) { for (int n = 0; n < N; n++) {
//........................................................................ //........................................................................
// Registers to store the distributions // Registers to store the distributions
@ -916,14 +944,16 @@ extern "C" void ScaLBL_D3Q19_Pressure(double *dist, double *Pressure, int N)
double f15 = dist[15 * N + n]; double f15 = dist[15 * N + n];
double f17 = dist[17 * N + n]; double f17 = dist[17 * N + n];
//.................Compute the velocity................................... //.................Compute the velocity...................................
Pressure[n] = 0.3333333333333333*(f0+f2+f1+f4+f3+f6+f5+f8+f7+f10+ Pressure[n] = 0.3333333333333333 *
f9+f12+f11+f14+f13+f16+f15+f18+f17); (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, extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish,
double Fy, double Fz) int Np, double rlx_setA,
{ double rlx_setB, double Fx, double Fy,
double Fz) {
// conserved momemnts // conserved momemnts
double rho, jx, jy, jz; double rho, jx, jy, jz;
// non-conserved moments // non-conserved moments
@ -1213,8 +1243,6 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
m17 -= fq; m17 -= fq;
m18 -= fq; m18 -= fq;
//........................................................................ //........................................................................
// READ THE DISTRIBUTIONS // READ THE DISTRIBUTIONS
// (read from opposite array due to previous swap operation) // (read from opposite array due to previous swap operation)
@ -1222,13 +1250,19 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
//..............incorporate external force................................................ //..............incorporate external force................................................
//..............carry out relaxation process............................................... //..............carry out relaxation process...............................................
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1); m1 = m1 +
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2); 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); m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6); m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8); m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho) - m9); 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); m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12); m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12);
m13 = m13 + rlx_setA * ((jx * jy / rho) - m13); m13 = m13 + rlx_setA * ((jx * jy / rho) - m13);
@ -1245,114 +1279,124 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
dist[n] = fq; dist[n] = fq;
// q = 1 // 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; dist[1 * Np + n] = fq;
// q=2 // 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; dist[2 * Np + n] = fq;
// q = 3 // 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; dist[3 * Np + n] = fq;
// q = 4 // 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; dist[4 * Np + n] = fq;
// q = 5 // 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; dist[5 * Np + n] = fq;
// q = 6 // 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; dist[6 * Np + n] = fq;
// q = 7 // q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (Fx + Fy);
dist[7 * Np + n] = fq; dist[7 * Np + n] = fq;
// q = 8 // 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 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy); 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; dist[8 * Np + n] = fq;
// q = 9 // q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (Fx - Fy);
dist[9 * Np + n] = fq; dist[9 * Np + n] = fq;
// q = 10 // q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (Fx - Fy);
dist[10 * Np + n] = fq; dist[10 * Np + n] = fq;
// q = 11 // q = 11
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8) 0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz); 0.08333333333 * (Fx + Fz);
dist[11 * Np + n] = fq; dist[11 * Np + n] = fq;
// q = 12 // q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 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); mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (Fx + Fz);
dist[12 * Np + n] = fq; dist[12 * Np + n] = fq;
// q = 13 // q = 13
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8) 0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz); 0.08333333333 * (Fx - Fz);
dist[13 * Np + n] = fq; dist[13 * Np + n] = fq;
// q= 14 // q= 14
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4) 0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz); 0.08333333333 * (Fx - Fz);
dist[14 * Np + n] = fq; dist[14 * Np + n] = fq;
// q = 15 // q = 15
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz); 0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
dist[15 * Np + n] = fq; dist[15 * Np + n] = fq;
// q = 16 // q = 16
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz); 0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
dist[16 * Np + n] = fq; dist[16 * Np + n] = fq;
// q = 17 // q = 17
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) 0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz); 0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
dist[17 * Np + n] = fq; dist[17 * Np + n] = fq;
// q = 18 // q = 18
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6) 0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz); 0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
dist[18 * Np + n] = fq; 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, extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist,
double Fy, double Fz) int start, int finish, int Np,
{ double rlx_setA, double rlx_setB,
double Fx, double Fy, double Fz) {
// conserved momemnts // conserved momemnts
double rho, jx, jy, jz; double rho, jx, jy, jz;
// non-conserved moments // non-conserved moments
@ -1370,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_V11 = 0.01388888888888889;
constexpr double mrt_V12 = 0.04166666666666666; constexpr double mrt_V12 = 0.04166666666666666;
int nread; int nread;
for (int n = start; n < finish; n++) { for (int n = start; n < finish; n++) {
// q=0 // q=0
@ -1392,7 +1435,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
m10 = -4.0 * fq; m10 = -4.0 * fq;
// f2 = dist[10*Np+n]; // 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[nread]; // reading the f2 data into register fq
//fq = dist[Np+n]; //fq = dist[Np+n];
rho += fq; rho += fq;
@ -1445,7 +1489,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
m11 -= fq; m11 -= fq;
m12 += 2.0 * fq; m12 += 2.0 * fq;
// q = 6 // q = 6
nread = neighborList[n + 5 * Np]; nread = neighborList[n + 5 * Np];
fq = dist[nread]; fq = dist[nread];
@ -1682,13 +1725,19 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
//..............incorporate external force................................................ //..............incorporate external force................................................
//..............carry out relaxation process............................................... //..............carry out relaxation process...............................................
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1); m1 = m1 +
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2); 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); m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6); m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8); m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho) - m9); 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); m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12); m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12);
m13 = m13 + rlx_setA * ((jx * jy / rho) - m13); m13 = m13 + rlx_setA * ((jx * jy / rho) - m13);
@ -1705,128 +1754,136 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
dist[n] = fq; dist[n] = fq;
// q = 1 // 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]; nread = neighborList[n + Np];
dist[nread] = fq; dist[nread] = fq;
// q=2 // 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]; nread = neighborList[n];
dist[nread] = fq; dist[nread] = fq;
// q = 3 // 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]; nread = neighborList[n + 3 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 4 // 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]; nread = neighborList[n + 2 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 5 // 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]; nread = neighborList[n + 5 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 6 // 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]; nread = neighborList[n + 4 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 7 // q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (Fx + Fy);
nread = neighborList[n + 7 * Np]; nread = neighborList[n + 7 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 8 // 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 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy); 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]; nread = neighborList[n + 6 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 9 // q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (Fx - Fy);
nread = neighborList[n + 9 * Np]; nread = neighborList[n + 9 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 10 // q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (Fx - Fy);
nread = neighborList[n + 8 * Np]; nread = neighborList[n + 8 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 11 // q = 11
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8) 0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz); 0.08333333333 * (Fx + Fz);
nread = neighborList[n + 11 * Np]; nread = neighborList[n + 11 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 12 // q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 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); mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (Fx + Fz);
nread = neighborList[n + 10 * Np]; nread = neighborList[n + 10 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 13 // q = 13
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8) 0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz); 0.08333333333 * (Fx - Fz);
nread = neighborList[n + 13 * Np]; nread = neighborList[n + 13 * Np];
dist[nread] = fq; dist[nread] = fq;
// q= 14 // q= 14
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4) 0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz); 0.08333333333 * (Fx - Fz);
nread = neighborList[n + 12 * Np]; nread = neighborList[n + 12 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 15 // q = 15
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz); 0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
nread = neighborList[n + 15 * Np]; nread = neighborList[n + 15 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 16 // q = 16
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz); 0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
nread = neighborList[n + 14 * Np]; nread = neighborList[n + 14 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 17 // q = 17
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) 0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz); 0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
nread = neighborList[n + 17 * Np]; nread = neighborList[n + 17 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 18 // q = 18
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6) 0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz); 0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
nread = neighborList[n + 16 * Np]; nread = neighborList[n + 16 * Np];
dist[nread] = fq; 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++) { for (int n = 0; n < Np; n++) {
@ -1884,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; int nread;
for (int n = 0; n < Np; n++) { for (int n = 0; n < Np; n++) {
@ -1920,7 +1977,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Compact(char * ID, int *neighborList, double
nread = neighborList[n + 16 * Np]; nread = neighborList[n + 16 * Np];
double f18 = dist[nread]; double f18 = dist[nread];
nread = neighborList[n + Np]; nread = neighborList[n + Np];
double f1 = dist[nread]; double f1 = dist[nread];
@ -1948,7 +2004,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Compact(char * ID, int *neighborList, double
nread = neighborList[n + 17 * Np]; nread = neighborList[n + 17 * Np];
double f17 = dist[nread]; double f17 = dist[nread];
nread = neighborList[n]; nread = neighborList[n];
dist[nread] = f1; dist[nread] = f1;
@ -1976,7 +2031,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Compact(char * ID, int *neighborList, double
nread = neighborList[n + 16 * Np]; nread = neighborList[n + 16 * Np];
dist[nread] = f17; dist[nread] = f17;
nread = neighborList[n + Np]; nread = neighborList[n + Np];
dist[nread] = f2; dist[nread] = f2;

View File

@ -16,7 +16,8 @@
*/ */
// CPU Functions for D3Q7 Lattice Boltzmann Methods // 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 // Pack distribution q into the send buffer for the listed lattice sites
// dist may be even or odd distributions stored by stream layout // dist may be even or odd distributions stored by stream layout
@ -27,7 +28,8 @@ extern "C" void ScaLBL_Scalar_Pack(int *list, int count, double *sendbuf, double
sendbuf[idx] = Data[n]; 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 // Pack distribution q into the send buffer for the listed lattice sites
// dist may be even or odd distributions stored by stream layout // dist may be even or odd distributions stored by stream layout
@ -52,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 // Get the value from the list -- note that n is the index is from the send (non-local) process
n = list[idx]; n = list[idx];
// unpack the distribution to the proper location // 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]; //dist[q*N+n] = recvbuf[start+idx];
} }
} }
extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf,
extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf, int number, double *Data, int N){ int number, double *Data, int N) {
//.................................................................................... //....................................................................................
// Pack distribution into the send buffer for the listed lattice sites // Pack distribution into the send buffer for the listed lattice sites
//.................................................................................... //....................................................................................
@ -68,13 +70,14 @@ extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf, int nu
for (component = 0; component < number; component++) { for (component = 0; component < number; component++) {
n = list[idx]; n = list[idx];
sendbuf[idx * number + component] = Data[number * n + component]; 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,
extern "C" void ScaLBL_UnpackDenD3Q7(int *list, int count, double *recvbuf, int number, double *Data, int N){ int number, double *Data, int N) {
//.................................................................................... //....................................................................................
// Unack distribution from the recv buffer // Unack distribution from the recv buffer
// Sum to the existing density value // Sum to the existing density value
@ -88,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; int n;
for (int idx = 0; idx < count; idx++) { for (int idx = 0; idx < count; idx++) {
n = list[idx]; n = list[idx];
@ -97,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; int n;
for (int idx = 0; idx < count; idx++) { for (int idx = 0; idx < count; idx++) {
n = list[idx]; n = list[idx];
@ -105,8 +110,8 @@ extern "C" void ScaLBL_D3Q7_Reflection_BC_Z(int *list, double *dist, int count,
dist[5 * Np + n] = f6; 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; int n, N;
N = Nx * Ny * Nz; N = Nx * Ny * Nz;
double value; double value;
@ -122,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_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_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; f_even[3 * N + n] = 0.1111111111111111 * value; //double(100*n)+6.f;
} } else {
else{
for (int q = 0; q < 3; q++) { for (int q = 0; q < 3; q++) {
f_even[q * N + n] = -1.0; f_even[q * N + n] = -1.0;
f_odd[q * N + n] = -1.0; f_odd[q * N + n] = -1.0;
@ -134,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; int i, j, k, n, nn, N;
// distributions // distributions
double f1, f2, f3, f4, f5, f6; double f1, f2, f3, f4, f5, f6;
@ -161,7 +165,8 @@ extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, in
// Retrieve odd distributions from neighboring nodes (swap convention) // Retrieve odd distributions from neighboring nodes (swap convention)
//........................................................................ //........................................................................
nn = n + 1; // neighbor index (pull 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){ //if (i+1<Nx){
f2 = disteven[N + nn]; // pull neighbor for distribution 2 f2 = disteven[N + nn]; // pull neighbor for distribution 2
if (!(f2 < 0.0)) { if (!(f2 < 0.0)) {
@ -171,7 +176,8 @@ extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, in
//} //}
//........................................................................ //........................................................................
nn = n + Nx; // neighbor index (pull convention) 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){ //if (j+1<Ny){
f4 = disteven[2 * N + nn]; // pull neighbor for distribution 4 f4 = disteven[2 * N + nn]; // pull neighbor for distribution 4
if (!(f4 < 0.0)) { if (!(f4 < 0.0)) {
@ -181,7 +187,8 @@ extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, in
} }
//........................................................................ //........................................................................
nn = n + Nx * Ny; // neighbor index (pull convention) 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){ //if (k+1<Nz){
f6 = disteven[3 * N + nn]; // pull neighbor for distribution 6 f6 = disteven[3 * N + nn]; // pull neighbor for distribution 6
if (!(f6 < 0.0)) { if (!(f6 < 0.0)) {
@ -194,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, extern "C" void ScaLBL_D3Q7_Density(char *ID, double *disteven, double *distodd,
int Nx, int Ny, int Nz) double *Den, int Nx, int Ny, int Nz) {
{
char id; char id;
int n; int n;
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;

View File

@ -1,7 +1,9 @@
// CPU Functions for D3Q7 Lattice Boltzmann Methods // CPU Functions for D3Q7 Lattice Boltzmann Methods
// Boundary Conditions // 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 idx;
int iq, ib; int iq, ib;
@ -11,12 +13,15 @@ extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist,double *BoundaryValue,i
ib = BounceBackSolid_list[idx]; ib = BounceBackSolid_list[idx];
value_b = BoundaryValue[ib]; //get boundary value from a solid site value_b = BoundaryValue[ib]; //get boundary value from a solid site
value_q = dist[iq]; 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,
extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist,double *BoundaryValue,int *BounceBackDist_list,int *BounceBackSolid_list,int N){ int *BounceBackDist_list,
int *BounceBackSolid_list, int N) {
int idx; int idx;
int iq, ib; int iq, ib;
@ -30,11 +35,13 @@ extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist,double *BoundaryValue,int
} }
} }
extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta_potential, double *ElectricField, double *SolidGrad, extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(
double epsilon_LB, double tau, double rho0,double den_scale, double h, double time_conv, double *dist, double *zeta_potential, double *ElectricField,
int *BounceBackDist_list, int *BounceBackSolid_list, int *FluidBoundary_list, double *SolidGrad, double epsilon_LB, double tau, double rho0,
double *lattice_weight, float *lattice_cx, float *lattice_cy, float *lattice_cz, double den_scale, double h, double time_conv, int *BounceBackDist_list,
int count, int Np){ int *BounceBackSolid_list, int *FluidBoundary_list, double *lattice_weight,
float *lattice_cx, float *lattice_cy, float *lattice_cz, int count,
int Np) {
int idx; int idx;
int iq, ib, ifluidBC; int iq, ib, ifluidBC;
@ -63,25 +70,35 @@ extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta
nsx = SolidGrad[ifluidBC + 0 * Np]; nsx = SolidGrad[ifluidBC + 0 * Np];
nsy = SolidGrad[ifluidBC + 1 * Np]; nsy = SolidGrad[ifluidBC + 1 * Np];
nsz = SolidGrad[ifluidBC + 2 * 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 //compute tangential electric field
Etx = Ex - E_mag_normal * nsx; Etx = Ex - E_mag_normal * nsx;
Ety = Ey - E_mag_normal * nsy; Ety = Ey - E_mag_normal * nsy;
Etz = Ez - E_mag_normal * nsz; 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; ubx = -epsilon_LB * value_b * Etx / (nu_LB * rho0) * time_conv *
uby = -epsilon_LB*value_b*Ety/(nu_LB*rho0)*time_conv*time_conv/(h*h*1.0e-12)/den_scale; 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; 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 //compute bounce-back distribution
LB_weight = lattice_weight[idx]; LB_weight = lattice_weight[idx];
cx = lattice_cx[idx]; cx = lattice_cx[idx];
cy = lattice_cy[idx]; cy = lattice_cy[idx];
cz = lattice_cz[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++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
double f0 = dist[n]; double f0 = dist[n];
@ -96,7 +113,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++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
double f0 = dist[n]; double f0 = dist[n];
@ -111,7 +131,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; int nread, nr5;
for (int idx = 0; idx < count; idx++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
@ -139,7 +163,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; int nread, nr6;
for (int idx = 0; idx < count; idx++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
@ -167,8 +195,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; int idx, n, nm;
for (idx = 0; idx < count; idx++) { for (idx = 0; idx < count; idx++) {
@ -178,8 +206,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; int idx, n, nm;
for (idx = 0; idx < count; idx++) { for (idx = 0; idx < count; idx++) {
@ -189,7 +217,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++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
double f0 = dist[n]; double f0 = dist[n];
@ -204,7 +235,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++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
double f0 = dist[n]; double f0 = dist[n];
@ -219,7 +253,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; int nread, nr5;
for (int idx = 0; idx < count; idx++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
@ -247,7 +285,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; int nread, nr6;
for (int idx = 0; idx < count; idx++) { for (int idx = 0; idx < count; idx++) {
int n = list[idx]; int n = list[idx];
@ -275,7 +317,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 //NOTE: FluxIn is the inward flux
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
double fsum_partial; double fsum_partial;
@ -293,13 +338,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_z(int *list, double *dist, double
uz = VelocityZ[n]; 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; dist[6 * Np + n] = f5;
} }
} }
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist,
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np){ double FluxIn, double tau,
double *VelocityZ, int count,
int Np) {
//NOTE: FluxIn is the inward flux //NOTE: FluxIn is the inward flux
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
double fsum_partial; double fsum_partial;
@ -317,12 +365,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist, double
uz = VelocityZ[n]; 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; 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 //NOTE: FluxIn is the inward flux
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
double fsum_partial; double fsum_partial;
@ -351,7 +403,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_z(int *d_neighborList, int *list,
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6; fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
uz = VelocityZ[n]; 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 // Unknown distributions
nr5 = d_neighborList[n + 4 * Np]; nr5 = d_neighborList[n + 4 * Np];
@ -359,7 +412,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 //NOTE: FluxIn is the inward flux
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
double fsum_partial; double fsum_partial;
@ -389,7 +445,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_Z(int *d_neighborList, int *list,
fsum_partial = f0 + f1 + f2 + f3 + f4 + f5; fsum_partial = f0 + f1 + f2 + f3 + f4 + f5;
uz = VelocityZ[n]; 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 // unknown distributions
nr6 = d_neighborList[n + 5 * Np]; nr6 = d_neighborList[n + 5 * Np];
@ -397,8 +454,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 //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
@ -415,13 +474,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; fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
uz = VelocityZ[n]; 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; 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 //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
@ -438,14 +500,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; fsum_partial = f0 + f1 + f2 + f3 + f4 + f5;
uz = VelocityZ[n]; 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; dist[5 * Np + n] = f6;
} }
} }
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_z(int *d_neighborList,
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) int *list, double *dist,
{ double FluxIn, double tau,
double *VelocityZ,
int count, int Np) {
//NOTE: FluxIn is the inward flux //NOTE: FluxIn is the inward flux
int n; int n;
int nread, nr5; int nread, nr5;
@ -476,7 +541,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; fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
uz = VelocityZ[n]; 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 // Unknown distributions
nr5 = d_neighborList[n + 4 * Np]; nr5 = d_neighborList[n + 4 * Np];
@ -484,8 +550,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 //NOTE: FluxIn is the inward flux
int n; int n;
int nread, nr5; int nread, nr5;
@ -514,7 +583,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; fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
uz = VelocityZ[n]; 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 // Unknown distributions
nr5 = d_neighborList[n + 4 * Np]; nr5 = d_neighborList[n + 4 * Np];
@ -522,10 +592,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,
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) int count, int Np) {
{
//NOTE: FluxIn is the inward flux //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
@ -543,13 +612,15 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_z(int *list, double *dis
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6; fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
uz = VelocityZ[n]; 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; 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 //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
@ -566,13 +637,15 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_Z(int *list, double *dis
fsum_partial = f0 + f1 + f2 + f3 + f4 + f5; fsum_partial = f0 + f1 + f2 + f3 + f4 + f5;
uz = VelocityZ[n]; 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; 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 //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
int nread, nr5; int nread, nr5;
@ -601,7 +674,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_z(int *d_neighborList, in
fsum_partial = f0 + f1 + f2 + f3 + f4 + f6; fsum_partial = f0 + f1 + f2 + f3 + f4 + f6;
uz = VelocityZ[n]; 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 // Unknown distributions
nr5 = d_neighborList[n + 4 * Np]; nr5 = d_neighborList[n + 4 * Np];
@ -609,8 +683,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 //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
int nread, nr6; int nread, nr6;
@ -639,7 +714,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_Z(int *d_neighborList, in
fsum_partial = f0 + f1 + f2 + f3 + f4 + f5; fsum_partial = f0 + f1 + f2 + f3 + f4 + f5;
uz = VelocityZ[n]; 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 // unknown distributions
nr6 = d_neighborList[n + 5 * Np]; nr6 = d_neighborList[n + 5 * Np];
@ -647,9 +723,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, extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_z(
double Di, double zi, double Vt, int count, int Np) 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 //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
@ -670,15 +747,17 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_z(int *list, double
Ez = ElectricField_Z[n]; Ez = ElectricField_Z[n];
uEPz = zi * Di / Vt * Ez; 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; dist[5 * Np + n] = f6;
} }
} }
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(
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, int *d_neighborList, int *list, double *dist, double FluxIn, double tau,
double Di, double zi, double Vt, int count, int Np) double *VelocityZ, double *ElectricField_Z, double Di, double zi, double Vt,
{ int count, int Np) {
//NOTE: FluxIn is the inward flux //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
int nread, nr5; int nread, nr5;
@ -711,7 +790,9 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(int *d_neighborList
Ez = ElectricField_Z[n]; Ez = ElectricField_Z[n];
uEPz = zi * Di / Vt * Ez; 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 // Unknown distributions
nr5 = d_neighborList[n + 4 * Np]; nr5 = d_neighborList[n + 4 * Np];
@ -719,9 +800,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, extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_Z(
double Di, double zi, double Vt, int count, int Np) 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 //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
double f0, f1, f2, f3, f4, f5, f6; double f0, f1, f2, f3, f4, f5, f6;
@ -742,13 +824,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_Z(int *list, double
Ez = ElectricField_Z[n]; Ez = ElectricField_Z[n];
uEPz = zi * Di / Vt * Ez; 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; 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, extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_Z(
double Di, double zi, double Vt, int count, int Np) 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 //NOTE: FluxIn is the inward flux
int idx, n; int idx, n;
int nread, nr6; int nread, nr6;
@ -781,21 +866,12 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_Z(int *d_neighborList
Ez = ElectricField_Z[n]; Ez = ElectricField_Z[n];
uEPz = zi * Di / Vt * Ez; 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 // unknown distributions
nr6 = d_neighborList[n + 5 * Np]; nr6 = d_neighborList[n + 5 * Np];
dist[nr6] = f6; dist[nr6] = f6;
} }
} }

View File

@ -19,9 +19,7 @@
#include <string.h> #include <string.h>
#include <mm_malloc.h> #include <mm_malloc.h>
extern "C" int ScaLBL_SetDevice(int rank){ extern "C" int ScaLBL_SetDevice(int rank) { return 0; }
return 0;
}
extern "C" void ScaLBL_AllocateZeroCopy(void **address, size_t size) { extern "C" void ScaLBL_AllocateZeroCopy(void **address, size_t size) {
//cudaMalloc(address,size); //cudaMalloc(address,size);
@ -43,22 +41,21 @@ extern "C" void ScaLBL_AllocateDeviceMemory(void** address, size_t size){
} }
} }
extern "C" void ScaLBL_FreeDeviceMemory(void* pointer){ extern "C" void ScaLBL_FreeDeviceMemory(void *pointer) { _mm_free(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); // cudaMemcpy(dest,source,size,cudaMemcpyHostToDevice);
memcpy(dest, source, size); memcpy(dest, source, size);
} }
extern "C" void ScaLBL_CopyToHost(void *dest, const void *source, size_t size) { extern "C" void ScaLBL_CopyToHost(void *dest, const void *source, size_t size) {
// cudaMemcpy(dest,source,size,cudaMemcpyDeviceToHost); // cudaMemcpy(dest,source,size,cudaMemcpyDeviceToHost);
memcpy(dest, source, size); 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); // cudaMemcpy(dest,source,size,cudaMemcpyDeviceToHost);
memcpy(dest, source, size); memcpy(dest, source, size);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,9 @@
#include <stdio.h> #include <stdio.h>
extern "C" void ScaLBL_D3Q7_AAodd_IonConcentration(int *neighborList, double *dist, double *Den, int start, int finish, int Np){ extern "C" void ScaLBL_D3Q7_AAodd_IonConcentration(int *neighborList,
double *dist, double *Den,
int start, int finish,
int Np) {
int n, nread; int n, nread;
double fq, Ci; double fq, Ci;
for (n = start; n < finish; n++) { for (n = start; n < finish; n++) {
@ -43,7 +46,9 @@ extern "C" void ScaLBL_D3Q7_AAodd_IonConcentration(int *neighborList, double *di
} }
} }
extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, int start, int finish, int Np){ extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den,
int start, int finish,
int Np) {
int n; int n;
double fq, Ci; double fq, Ci;
for (n = start; n < finish; n++) { for (n = start; n < finish; n++) {
@ -80,8 +85,13 @@ extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, i
} }
} }
extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist,
double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ double *Den, double *FluxDiffusive,
double *FluxAdvective,
double *FluxElectrical, double *Velocity,
double *ElectricField, double Di, int zi,
double rlx, double Vt, int start,
int finish, int Np) {
int n; int n;
double Ci; double Ci;
double ux, uy, uz; double ux, uy, uz;
@ -144,28 +154,35 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *D
dist[n] = f0 * (1.0 - rlx) + rlx * 0.25 * Ci; dist[n] = f0 * (1.0 - rlx) + rlx * 0.25 * Ci;
// q = 1 // q = 1
dist[nr2] = f1*(1.0-rlx) + rlx*0.125*Ci*(1.0+4.0*(ux+uEPx)); dist[nr2] =
f1 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 + 4.0 * (ux + uEPx));
// q=2 // q=2
dist[nr1] = f2*(1.0-rlx) + rlx*0.125*Ci*(1.0-4.0*(ux+uEPx)); dist[nr1] =
f2 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 - 4.0 * (ux + uEPx));
// q = 3 // q = 3
dist[nr4] = f3*(1.0-rlx) + rlx*0.125*Ci*(1.0+4.0*(uy+uEPy)); dist[nr4] =
f3 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 + 4.0 * (uy + uEPy));
// q = 4 // q = 4
dist[nr3] = f4*(1.0-rlx) + rlx*0.125*Ci*(1.0-4.0*(uy+uEPy)); dist[nr3] =
f4 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 - 4.0 * (uy + uEPy));
// q = 5 // q = 5
dist[nr6] = f5*(1.0-rlx) + rlx*0.125*Ci*(1.0+4.0*(uz+uEPz)); dist[nr6] =
f5 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 + 4.0 * (uz + uEPz));
// q = 6 // q = 6
dist[nr5] = f6*(1.0-rlx) + rlx*0.125*Ci*(1.0-4.0*(uz+uEPz)); dist[nr5] =
f6 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 - 4.0 * (uz + uEPz));
} }
} }
extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective, double *FluxElectrical, double *Velocity, double *ElectricField, extern "C" void ScaLBL_D3Q7_AAeven_Ion(
double Di, int zi, double rlx, double Vt, int start, int finish, int Np){ double *dist, double *Den, double *FluxDiffusive, double *FluxAdvective,
double *FluxElectrical, double *Velocity, double *ElectricField, double Di,
int zi, double rlx, double Vt, int start, int finish, int Np) {
int n; int n;
double Ci; double Ci;
double ux, uy, uz; double ux, uy, uz;
@ -214,29 +231,33 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *FluxDi
dist[n] = f0 * (1.0 - rlx) + rlx * 0.25 * Ci; dist[n] = f0 * (1.0 - rlx) + rlx * 0.25 * Ci;
// q = 1 // q = 1
dist[1*Np+n] = f1*(1.0-rlx) + rlx*0.125*Ci*(1.0+4.0*(ux+uEPx)); dist[1 * Np + n] =
f1 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 + 4.0 * (ux + uEPx));
// q=2 // q=2
dist[2*Np+n] = f2*(1.0-rlx) + rlx*0.125*Ci*(1.0-4.0*(ux+uEPx)); dist[2 * Np + n] =
f2 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 - 4.0 * (ux + uEPx));
// q = 3 // q = 3
dist[3*Np+n] = f3*(1.0-rlx) + rlx*0.125*Ci*(1.0+4.0*(uy+uEPy)); dist[3 * Np + n] =
f3 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 + 4.0 * (uy + uEPy));
// q = 4 // q = 4
dist[4*Np+n] = f4*(1.0-rlx) + rlx*0.125*Ci*(1.0-4.0*(uy+uEPy)); dist[4 * Np + n] =
f4 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 - 4.0 * (uy + uEPy));
// q = 5 // q = 5
dist[5*Np+n] = f5*(1.0-rlx) + rlx*0.125*Ci*(1.0+4.0*(uz+uEPz)); dist[5 * Np + n] =
f5 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 + 4.0 * (uz + uEPz));
// q = 6 // q = 6
dist[6*Np+n] = f6*(1.0-rlx) + rlx*0.125*Ci*(1.0-4.0*(uz+uEPz)); dist[6 * Np + n] =
f6 * (1.0 - rlx) + rlx * 0.125 * Ci * (1.0 - 4.0 * (uz + uEPz));
} }
} }
extern "C" void ScaLBL_D3Q7_Ion_Init(double *dist, double *Den, double DenInit, int Np) extern "C" void ScaLBL_D3Q7_Ion_Init(double *dist, double *Den, double DenInit,
{ int Np) {
int n; int n;
for (n = 0; n < Np; n++) { for (n = 0; n < Np; n++) {
dist[0 * Np + n] = 0.25 * DenInit; dist[0 * Np + n] = 0.25 * DenInit;
@ -250,8 +271,8 @@ extern "C" void ScaLBL_D3Q7_Ion_Init(double *dist, double *Den, double DenInit,
} }
} }
extern "C" void ScaLBL_D3Q7_Ion_Init_FromFile(double *dist, double *Den, int Np) extern "C" void ScaLBL_D3Q7_Ion_Init_FromFile(double *dist, double *Den,
{ int Np) {
int n; int n;
double DenInit; double DenInit;
for (n = 0; n < Np; n++) { for (n = 0; n < Np; n++) {
@ -266,13 +287,17 @@ extern "C" void ScaLBL_D3Q7_Ion_Init_FromFile(double *dist, double *Den, int Np)
} }
} }
extern "C" void ScaLBL_D3Q7_Ion_ChargeDensity(double *Den, double *ChargeDensity, int IonValence, int ion_component, int start, int finish, int Np){ extern "C" void ScaLBL_D3Q7_Ion_ChargeDensity(double *Den,
double *ChargeDensity,
int IonValence, int ion_component,
int start, int finish, int Np) {
int n; int n;
double Ci; //ion concentration of species i double Ci; //ion concentration of species i
double CD; //charge density double CD; //charge density
double CD_tmp; double CD_tmp;
double F = 96485.0;//Faraday's constant; unit[C/mol]; F=e*Na, where Na is the Avogadro constant double F =
96485.0; //Faraday's constant; unit[C/mol]; F=e*Na, where Na is the Avogadro constant
for (n = start; n < finish; n++) { for (n = start; n < finish; n++) {
Ci = Den[n + ion_component * Np]; Ci = Den[n + ion_component * Np];
@ -281,4 +306,3 @@ extern "C" void ScaLBL_D3Q7_Ion_ChargeDensity(double *Den, double *ChargeDensity
ChargeDensity[n] = CD * (ion_component > 0) + CD_tmp; ChargeDensity[n] = CD * (ion_component > 0) + CD_tmp;
} }
} }

View File

@ -14,8 +14,8 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
extern "C" void INITIALIZE(char *ID, double *f_even, double *f_odd, int Nx, int Ny, int Nz) extern "C" void INITIALIZE(char *ID, double *f_even, double *f_odd, int Nx,
{ int Ny, int Nz) {
int n, N; int n, N;
N = Nx * Ny * Nz; N = Nx * Ny * Nz;
@ -41,8 +41,7 @@ extern "C" void INITIALIZE(char *ID, double *f_even, double *f_odd, int Nx, int
f_even[8 * N + n] = 0.0277777777777778; //double(100*n)+16.f; f_even[8 * N + n] = 0.0277777777777778; //double(100*n)+16.f;
f_odd[8 * N + n] = 0.0277777777777778; //double(100*n)+17.f; f_odd[8 * N + n] = 0.0277777777777778; //double(100*n)+17.f;
f_even[9 * N + n] = 0.0277777777777778; //double(100*n)+18.f; f_even[9 * N + n] = 0.0277777777777778; //double(100*n)+18.f;
} } else {
else{
for (int q = 0; q < 9; q++) { for (int q = 0; q < 9; q++) {
f_even[q * N + n] = -1.0; f_even[q * N + n] = -1.0;
f_odd[q * N + n] = -1.0; f_odd[q * N + n] = -1.0;
@ -50,11 +49,10 @@ extern "C" void INITIALIZE(char *ID, double *f_even, double *f_odd, int Nx, int
f_even[9 * N + n] = -1.0; f_even[9 * N + n] = -1.0;
} }
} }
} }
extern "C" void Compute_VELOCITY(char *ID, double *disteven, double *distodd, double *vel, int Nx, int Ny, int Nz) extern "C" void Compute_VELOCITY(char *ID, double *disteven, double *distodd,
{ double *vel, int Nx, int Ny, int Nz) {
int n, N; int n, N;
// distributions // distributions
double f1, f2, f3, f4, f5, f6, f7, f8, f9; double f1, f2, f3, f4, f5, f6, f7, f8, f9;
@ -96,16 +94,15 @@ extern "C" void Compute_VELOCITY(char *ID, double *disteven, double *distodd, do
vel[N + n] = vy; vel[N + n] = vy;
vel[2 * N + n] = vz; vel[2 * N + n] = vz;
//........................................................................ //........................................................................
} }
} }
} }
//************************************************************************* //*************************************************************************
extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd, int Nx, int Ny, int Nz, extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd,
double rlx_setA, double rlx_setB, double Fx, double Fy, double Fz) int Nx, int Ny, int Nz, double rlx_setA,
{ double rlx_setB, double Fx, double Fy,
double Fz) {
int n, N; int n, N;
// distributions // distributions
@ -149,19 +146,27 @@ extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd, in
f17 = disteven[9 * N + n]; f17 = disteven[9 * N + n];
//........................................................................ //........................................................................
//....................compute the moments............................................... //....................compute the moments...............................................
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 +
m1 = -30*f0-11*(f2+f1+f4+f3+f6+f5)+8*(f8+f7+f10+f9+f12+f11+f14+f13+f16+f15+f18 +f17); f11 + f14 + f13 + f16 + f15 + f18 + f17;
m2 = 12*f0-4*(f2+f1 +f4+f3+f6 +f5)+f8+f7+f10+f9+f12+f11+f14+f13+f16+f15+f18+f17; m1 = -30 * f0 - 11 * (f2 + f1 + f4 + f3 + f6 + f5) +
8 * (f8 + f7 + f10 + f9 + f12 + f11 + f14 + f13 + f16 + f15 +
f18 + f17);
m2 = 12 * f0 - 4 * (f2 + f1 + f4 + f3 + f6 + f5) + f8 + f7 + f10 +
f9 + f12 + f11 + f14 + f13 + f16 + f15 + f18 + f17;
jx = f1 - f2 + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14; jx = f1 - f2 + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14;
m4 = 4 * (-f1 + f2) + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14; m4 = 4 * (-f1 + f2) + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14;
jy = f3 - f4 + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18; jy = f3 - f4 + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18;
m6 = -4 * (f3 - f4) + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18; m6 = -4 * (f3 - f4) + f7 - f8 - f9 + f10 + f15 - f16 + f17 - f18;
jz = f5 - f6 + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18; jz = f5 - f6 + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18;
m8 = -4 * (f5 - f6) + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18; m8 = -4 * (f5 - f6) + f11 - f12 - f13 + f14 + f15 - f16 - f17 + f18;
m9 = 2*(f1+f2)-f3-f4-f5-f6+f7+f8+f9+f10+f11+f12+f13+f14-2*(f15+f16+f17+f18); m9 = 2 * (f1 + f2) - f3 - f4 - f5 - f6 + f7 + f8 + f9 + f10 + f11 +
m10 = -4*(f1+f2)+2*(f4+f3+f6+f5)+f8+f7+f10+f9+f12+f11+f14+f13-2*(f16+f15+f18+f17); f12 + f13 + f14 - 2 * (f15 + f16 + f17 + f18);
m11 = f4+f3-f6-f5+f8+f7+f10+f9-f12-f11-f14-f13; m10 = -4 * (f1 + f2) + 2 * (f4 + f3 + f6 + f5) + f8 + f7 + f10 +
m12 = -2*(f4+f3-f6-f5)+f8+f7+f10+f9-f12-f11-f14-f13; f9 + f12 + f11 + f14 + f13 - 2 * (f16 + f15 + f18 + f17);
m11 =
f4 + f3 - f6 - f5 + f8 + f7 + f10 + f9 - f12 - f11 - f14 - f13;
m12 = -2 * (f4 + f3 - f6 - f5) + f8 + f7 + f10 + f9 - f12 - f11 -
f14 - f13;
m13 = f8 + f7 - f10 - f9; m13 = f8 + f7 - f10 - f9;
m14 = f16 + f15 - f18 - f17; m14 = f16 + f15 - f18 - f17;
m15 = f12 + f11 - f14 - f13; m15 = f12 + f11 - f14 - f13;
@ -173,13 +178,20 @@ extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd, in
//jy += 0.5*Fy; //jy += 0.5*Fy;
//jz += 0.5*Fz; //jz += 0.5*Fz;
//..............carry out relaxation process............................................... //..............carry out relaxation process...............................................
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1); m1 = m1 + rlx_setA * ((19 * (jx * jx + jy * jy + jz * jz) / rho -
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2); 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); m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6); m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8); m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/rho) - m9); m9 = m9 +
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10); 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);
m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11); m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12); m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12);
m13 = m13 + rlx_setA * ((jx * jy / rho) - m13); m13 = m13 + rlx_setA * ((jx * jy / rho) - m13);
@ -189,59 +201,86 @@ extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd, in
m17 = m17 + rlx_setB * (-m17); m17 = m17 + rlx_setB * (-m17);
m18 = m18 + rlx_setB * (-m18); m18 = m18 + rlx_setB * (-m18);
//.................inverse transformation...................................................... //.................inverse transformation......................................................
f0 = 0.05263157894736842*rho-0.012531328320802*m1+0.04761904761904762*m2; f0 = 0.05263157894736842 * rho - 0.012531328320802 * m1 +
f1 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2 0.04761904761904762 * m2;
+0.1*(jx-m4)+0.05555555555555555*(m9-m10); f1 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
f2 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2 0.01587301587301587 * m2 + 0.1 * (jx - m4) +
+0.1*(m4-jx)+0.05555555555555555*(m9-m10); 0.05555555555555555 * (m9 - m10);
f3 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2 f2 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
+0.1*(jy-m6)+0.02777777777777778*(m10-m9)+0.08333333333333333*(m11-m12); 0.01587301587301587 * m2 + 0.1 * (m4 - jx) +
f4 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2 0.05555555555555555 * (m9 - m10);
+0.1*(m6-jy)+0.02777777777777778*(m10-m9)+0.08333333333333333*(m11-m12); f3 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
f5 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2 0.01587301587301587 * m2 + 0.1 * (jy - m6) +
+0.1*(jz-m8)+0.02777777777777778*(m10-m9)+0.08333333333333333*(m12-m11); 0.02777777777777778 * (m10 - m9) +
f6 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2 0.08333333333333333 * (m11 - m12);
+0.1*(m8-jz)+0.02777777777777778*(m10-m9)+0.08333333333333333*(m12-m11); f4 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
f7 = 0.05263157894736842*rho+0.003341687552213868*m1+0.003968253968253968*m2+0.1*(jx+jy)+0.025*(m4+m6) 0.01587301587301587 * m2 + 0.1 * (m6 - jy) +
+0.02777777777777778*m9+0.01388888888888889*m10+0.08333333333333333*m11 0.02777777777777778 * (m10 - m9) +
+0.04166666666666666*m12+0.25*m13+0.125*(m16-m17); 0.08333333333333333 * (m11 - m12);
f8 = 0.05263157894736842*rho+0.003341687552213868*m1+0.003968253968253968*m2-0.1*(jx+jy)-0.025*(m4+m6) f5 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
+0.02777777777777778*m9+0.01388888888888889*m10+0.08333333333333333*m11 0.01587301587301587 * m2 + 0.1 * (jz - m8) +
+0.04166666666666666*m12+0.25*m13+0.125*(m17-m16); 0.02777777777777778 * (m10 - m9) +
f9 = 0.05263157894736842*rho+0.003341687552213868*m1+0.003968253968253968*m2+0.1*(jx-jy)+0.025*(m4-m6) 0.08333333333333333 * (m12 - m11);
+0.02777777777777778*m9+0.01388888888888889*m10+0.08333333333333333*m11 f6 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
+0.04166666666666666*m12-0.25*m13+0.125*(m16+m17); 0.01587301587301587 * m2 + 0.1 * (m8 - jz) +
f10 = 0.05263157894736842*rho+0.003341687552213868*m1+0.003968253968253968*m2+0.1*(jy-jx)+0.025*(m6-m4) 0.02777777777777778 * (m10 - m9) +
+0.02777777777777778*m9+0.01388888888888889*m10+0.08333333333333333*m11 0.08333333333333333 * (m12 - m11);
+0.04166666666666666*m12-0.25*m13-0.125*(m16+m17); f7 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
f11 = 0.05263157894736842*rho+0.003341687552213868*m1 0.003968253968253968 * m2 + 0.1 * (jx + jy) +
+0.003968253968253968*m2+0.1*(jx+jz)+0.025*(m4+m8) 0.025 * (m4 + m6) + 0.02777777777777778 * m9 +
+0.02777777777777778*m9+0.01388888888888889*m10-0.08333333333333333*m11 0.01388888888888889 * m10 + 0.08333333333333333 * m11 +
-0.04166666666666666*m12+0.25*m15+0.125*(m18-m16); 0.04166666666666666 * m12 + 0.25 * m13 + 0.125 * (m16 - m17);
f12 = 0.05263157894736842*rho+0.003341687552213868*m1 f8 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
+0.003968253968253968*m2-0.1*(jx+jz)-0.025*(m4+m8) 0.003968253968253968 * m2 - 0.1 * (jx + jy) -
+0.02777777777777778*m9+0.01388888888888889*m10-0.08333333333333333*m11 0.025 * (m4 + m6) + 0.02777777777777778 * m9 +
-0.04166666666666666*m12+0.25*m15+0.125*(m16-m18); 0.01388888888888889 * m10 + 0.08333333333333333 * m11 +
f13 = 0.05263157894736842*rho+0.003341687552213868*m1 0.04166666666666666 * m12 + 0.25 * m13 + 0.125 * (m17 - m16);
+0.003968253968253968*m2+0.1*(jx-jz)+0.025*(m4-m8) f9 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
+0.02777777777777778*m9+0.01388888888888889*m10-0.08333333333333333*m11 0.003968253968253968 * m2 + 0.1 * (jx - jy) +
-0.04166666666666666*m12-0.25*m15-0.125*(m16+m18); 0.025 * (m4 - m6) + 0.02777777777777778 * m9 +
f14 = 0.05263157894736842*rho+0.003341687552213868*m1 0.01388888888888889 * m10 + 0.08333333333333333 * m11 +
+0.003968253968253968*m2+0.1*(jz-jx)+0.025*(m8-m4) 0.04166666666666666 * m12 - 0.25 * m13 + 0.125 * (m16 + m17);
+0.02777777777777778*m9+0.01388888888888889*m10-0.08333333333333333*m11 f10 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
-0.04166666666666666*m12-0.25*m15+0.125*(m16+m18); 0.003968253968253968 * m2 + 0.1 * (jy - jx) +
f15 = 0.05263157894736842*rho+0.003341687552213868*m1 0.025 * (m6 - m4) + 0.02777777777777778 * m9 +
+0.003968253968253968*m2+0.1*(jy+jz)+0.025*(m6+m8) 0.01388888888888889 * m10 + 0.08333333333333333 * m11 +
-0.05555555555555555*m9-0.02777777777777778*m10+0.25*m14+0.125*(m17-m18); 0.04166666666666666 * m12 - 0.25 * m13 - 0.125 * (m16 + m17);
f16 = 0.05263157894736842*rho+0.003341687552213868*m1 f11 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
+0.003968253968253968*m2-0.1*(jy+jz)-0.025*(m6+m8) 0.003968253968253968 * m2 + 0.1 * (jx + jz) +
-0.05555555555555555*m9-0.02777777777777778*m10+0.25*m14+0.125*(m18-m17); 0.025 * (m4 + m8) + 0.02777777777777778 * m9 +
f17 = 0.05263157894736842*rho+0.003341687552213868*m1 0.01388888888888889 * m10 - 0.08333333333333333 * m11 -
+0.003968253968253968*m2+0.1*(jy-jz)+0.025*(m6-m8) 0.04166666666666666 * m12 + 0.25 * m15 + 0.125 * (m18 - m16);
-0.05555555555555555*m9-0.02777777777777778*m10-0.25*m14+0.125*(m17+m18); f12 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
f18 = 0.05263157894736842*rho+0.003341687552213868*m1 0.003968253968253968 * m2 - 0.1 * (jx + jz) -
+0.003968253968253968*m2+0.1*(jz-jy)+0.025*(m8-m6) 0.025 * (m4 + m8) + 0.02777777777777778 * m9 +
-0.05555555555555555*m9-0.02777777777777778*m10-0.25*m14-0.125*(m17+m18); 0.01388888888888889 * m10 - 0.08333333333333333 * m11 -
0.04166666666666666 * m12 + 0.25 * m15 + 0.125 * (m16 - m18);
f13 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 + 0.1 * (jx - jz) +
0.025 * (m4 - m8) + 0.02777777777777778 * m9 +
0.01388888888888889 * m10 - 0.08333333333333333 * m11 -
0.04166666666666666 * m12 - 0.25 * m15 - 0.125 * (m16 + m18);
f14 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 + 0.1 * (jz - jx) +
0.025 * (m8 - m4) + 0.02777777777777778 * m9 +
0.01388888888888889 * m10 - 0.08333333333333333 * m11 -
0.04166666666666666 * m12 - 0.25 * m15 + 0.125 * (m16 + m18);
f15 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 + 0.1 * (jy + jz) +
0.025 * (m6 + m8) - 0.05555555555555555 * m9 -
0.02777777777777778 * m10 + 0.25 * m14 + 0.125 * (m17 - m18);
f16 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 - 0.1 * (jy + jz) -
0.025 * (m6 + m8) - 0.05555555555555555 * m9 -
0.02777777777777778 * m10 + 0.25 * m14 + 0.125 * (m18 - m17);
f17 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 + 0.1 * (jy - jz) +
0.025 * (m6 - m8) - 0.05555555555555555 * m9 -
0.02777777777777778 * m10 - 0.25 * m14 + 0.125 * (m17 + m18);
f18 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 + 0.1 * (jz - jy) +
0.025 * (m8 - m6) - 0.05555555555555555 * m9 -
0.02777777777777778 * m10 - 0.25 * m14 - 0.125 * (m17 + m18);
//....................................................................................................... //.......................................................................................................
// incorporate external force // incorporate external force
f1 += 0.16666666 * Fx; f1 += 0.16666666 * Fx;
@ -288,5 +327,3 @@ extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd, in
} }
} }
} }

View File

@ -1,11 +1,14 @@
/* Implement Mixed Gradient (Lee et al. JCP 2016)*/ /* Implement Mixed Gradient (Lee et al. JCP 2016)*/
extern "C" void ScaLBL_D3Q19_MixedGradient(int *Map, double *Phi, double *Gradient, int start, int finish, int Np, int Nx, int Ny, int Nz) extern "C" void ScaLBL_D3Q19_MixedGradient(int *Map, double *Phi,
{ double *Gradient, int start,
static int D3Q19[18][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}, int finish, int Np, int Nx, int Ny,
{1,1,0},{-1,-1,0},{1,-1,0},{-1,1,0}, int Nz) {
{1,0,1},{-1,0,-1},{1,0,-1},{-1,0,1}, static int D3Q19[18][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0},
{0,1,1},{0,-1,-1},{0,1,-1},{0,-1,1}}; {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}};
int i, j, k, n; int i, j, k, n;
int np, np2, nm; // neighbors int np, np2, nm; // neighbors

View File

@ -1,5 +1,8 @@
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_ElectricPotential(int *neighborList,int *Map, double *dist, double *Psi, int start, int finish, int Np){ extern "C" void
ScaLBL_D3Q7_AAodd_Poisson_ElectricPotential(int *neighborList, int *Map,
double *dist, double *Psi,
int start, int finish, int Np) {
int n; int n;
double psi; //electric potential double psi; //electric potential
double fq; double fq;
@ -47,7 +50,8 @@ extern "C" void ScaLBL_D3Q7_AAodd_Poisson_ElectricPotential(int *neighborList,in
} }
} }
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_ElectricPotential(int *Map, double *dist, double *Psi, int start, int finish, int Np){ extern "C" void ScaLBL_D3Q7_AAeven_Poisson_ElectricPotential(
int *Map, double *dist, double *Psi, int start, int finish, int Np) {
int n; int n;
double psi; //electric potential double psi; //electric potential
double fq; double fq;
@ -88,7 +92,11 @@ extern "C" void ScaLBL_D3Q7_AAeven_Poisson_ElectricPotential(int *Map, double *d
} }
} }
extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList, int *Map, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,int start, int finish, int Np){ extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList, int *Map,
double *dist, double *Den_charge,
double *Psi, double *ElectricField,
double tau, double epsilon_LB,
int start, int finish, int Np) {
int n; int n;
double psi; //electric potential double psi; //electric potential
double Ex, Ey, Ez; //electric field double Ex, Ey, Ez; //electric field
@ -131,8 +139,10 @@ extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList, int *Map, double *d
nr6 = neighborList[n + 5 * Np]; nr6 = neighborList[n + 5 * Np];
f6 = dist[nr6]; f6 = dist[nr6];
Ex = (f1-f2)*rlx*4.0;//NOTE the unit of electric field here is V/lu Ex = (f1 - f2) * rlx *
Ey = (f3-f4)*rlx*4.0;//factor 4.0 is D3Q7 lattice squared speed of sound 4.0; //NOTE the unit of electric field here is V/lu
Ey = (f3 - f4) * rlx *
4.0; //factor 4.0 is D3Q7 lattice squared speed of sound
Ez = (f5 - f6) * rlx * 4.0; Ez = (f5 - f6) * rlx * 4.0;
ElectricField[n + 0 * Np] = Ex; ElectricField[n + 0 * Np] = Ex;
ElectricField[n + 1 * Np] = Ey; ElectricField[n + 1 * Np] = Ey;
@ -162,7 +172,11 @@ extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList, int *Map, double *d
} }
} }
extern "C" void ScaLBL_D3Q7_AAeven_Poisson(int *Map, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,int start, int finish, int Np){ extern "C" void ScaLBL_D3Q7_AAeven_Poisson(int *Map, double *dist,
double *Den_charge, double *Psi,
double *ElectricField, double tau,
double epsilon_LB, int start,
int finish, int Np) {
int n; int n;
double psi; //electric potential double psi; //electric potential
double Ex, Ey, Ez; //electric field double Ex, Ey, Ez; //electric field
@ -187,9 +201,10 @@ extern "C" void ScaLBL_D3Q7_AAeven_Poisson(int *Map, double *dist, double *Den_c
f5 = dist[6 * Np + n]; f5 = dist[6 * Np + n];
f6 = dist[5 * Np + n]; f6 = dist[5 * Np + n];
Ex = (f1 - f2) * rlx *
Ex = (f1-f2)*rlx*4.0;//NOTE the unit of electric field here is V/lu 4.0; //NOTE the unit of electric field here is V/lu
Ey = (f3-f4)*rlx*4.0;//factor 4.0 is D3Q7 lattice squared speed of sound Ey = (f3 - f4) * rlx *
4.0; //factor 4.0 is D3Q7 lattice squared speed of sound
Ez = (f5 - f6) * rlx * 4.0; Ez = (f5 - f6) * rlx * 4.0;
ElectricField[n + 0 * Np] = Ex; ElectricField[n + 0 * Np] = Ex;
ElectricField[n + 1 * Np] = Ey; ElectricField[n + 1 * Np] = Ey;
@ -219,8 +234,8 @@ extern "C" void ScaLBL_D3Q7_AAeven_Poisson(int *Map, double *dist, double *Den_c
} }
} }
extern "C" void ScaLBL_D3Q7_Poisson_Init(int *Map, double *dist, double *Psi, int start, int finish, int Np) extern "C" void ScaLBL_D3Q7_Poisson_Init(int *Map, double *dist, double *Psi,
{ int start, int finish, int Np) {
int n; int n;
int ijk; int ijk;
for (n = start; n < finish; n++) { for (n = start; n < finish; n++) {
@ -235,7 +250,10 @@ extern "C" void ScaLBL_D3Q7_Poisson_Init(int *Map, double *dist, double *Psi, in
} }
} }
extern "C" void ScaLBL_D3Q7_PoissonResidualError(int *neighborList, int *Map, double *ResidualError, double *Psi, double *Den_charge, double epsilon_LB,int strideY, int strideZ,int start, int finish){ extern "C" void ScaLBL_D3Q7_PoissonResidualError(
int *neighborList, int *Map, double *ResidualError, double *Psi,
double *Den_charge, double epsilon_LB, int strideY, int strideZ, int start,
int finish) {
int n, nn, ijk; int n, nn, ijk;
double psi; //electric potential double psi; //electric potential
@ -311,7 +329,11 @@ extern "C" void ScaLBL_D3Q7_PoissonResidualError(int *neighborList, int *Map, do
nn = ijk - strideZ + strideY; // neighbor index (get convention) nn = ijk - strideZ + strideY; // neighbor index (get convention)
m18 = Psi[nn]; // get neighbor for phi - 18 m18 = Psi[nn]; // get neighbor for phi - 18
psi_Laplacian = 2.0*3.0/18.0*(m1+m2+m3+m4+m5+m6-6*psi+0.5*(m7+m8+m9+m10+m11+m12+m13+m14+m15+m16+m17+m18-12*psi));//Laplacian of electric potential psi_Laplacian =
2.0 * 3.0 / 18.0 *
(m1 + m2 + m3 + m4 + m5 + m6 - 6 * psi +
0.5 * (m7 + m8 + m9 + m10 + m11 + m12 + m13 + m14 + m15 + m16 +
m17 + m18 - 12 * psi)); //Laplacian of electric potential
residual_error = psi_Laplacian + rho_e / epsilon_LB; residual_error = psi_Laplacian + rho_e / epsilon_LB;
ResidualError[n] = residual_error; ResidualError[n] = residual_error;
} }

View File

@ -1,7 +1,10 @@
#include <stdio.h> #include <stdio.h>
extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB, double Gx, double Gy, double Gz,double rho0, double den_scale, double h, double time_conv, int start, int finish, int Np) extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(
{ double *dist, double *Velocity, double *ChargeDensity,
double *ElectricField, double rlx_setA, double rlx_setB, double Gx,
double Gy, double Gz, double rho0, double den_scale, double h,
double time_conv, int start, int finish, int Np) {
double fq; double fq;
// conserved momemnts // conserved momemnts
double rho, jx, jy, jz; double rho, jx, jy, jz;
@ -35,9 +38,14 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
Ey = ElectricField[n + 1 * Np]; Ey = ElectricField[n + 1 * Np];
Ez = ElectricField[n + 2 * Np]; Ez = ElectricField[n + 2 * Np];
//compute total body force, including input body force (Gx,Gy,Gz) //compute total body force, including input body force (Gx,Gy,Gz)
Fx = Gx + rhoE*Ex*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale;//the extra factors at the end necessarily convert unit from phys to LB Fx =
Fy = Gy + rhoE*Ey*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale; Gx +
Fz = Gz + rhoE*Ez*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale; rhoE * Ex * (time_conv * time_conv) / (h * h * 1.0e-12) /
den_scale; //the extra factors at the end necessarily convert unit from phys to LB
Fy = Gy + rhoE * Ey * (time_conv * time_conv) / (h * h * 1.0e-12) /
den_scale;
Fz = Gz + rhoE * Ez * (time_conv * time_conv) / (h * h * 1.0e-12) /
den_scale;
// q=0 // q=0
fq = dist[n]; fq = dist[n];
@ -317,7 +325,6 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
Velocity[Np + n] = uy; Velocity[Np + n] = uy;
Velocity[2 * Np + n] = uz; Velocity[2 * Np + n] = uz;
//........................................................................ //........................................................................
// READ THE DISTRIBUTIONS // READ THE DISTRIBUTIONS
// (read from opposite array due to previous swap operation) // (read from opposite array due to previous swap operation)
@ -325,13 +332,19 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
//..............incorporate external force................................................ //..............incorporate external force................................................
//..............carry out relaxation process............................................... //..............carry out relaxation process...............................................
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho0 - 11*rho) - m1); m1 = m1 +
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho0) - m2); rlx_setA *
((19 * (jx * jx + jy * jy + jz * jz) / rho0 - 11 * rho) - m1);
m2 = m2 +
rlx_setA *
((3 * rho - 5.5 * (jx * jx + jy * jy + jz * jz) / rho0) - m2);
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4); m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6); m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8); m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho0) - m9); m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho0) - 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) / rho0) - m11); m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho0) - m11);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho0) - m12); m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho0) - m12);
m13 = m13 + rlx_setA * ((jx * jy / rho0) - m13); m13 = m13 + rlx_setA * ((jx * jy / rho0) - m13);
@ -348,113 +361,125 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
dist[n] = fq; dist[n] = fq;
// q = 1 // 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; dist[1 * Np + n] = fq;
// q=2 // 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; dist[2 * Np + n] = fq;
// q = 3 // 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; dist[3 * Np + n] = fq;
// q = 4 // 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; dist[4 * Np + n] = fq;
// q = 5 // 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; dist[5 * Np + n] = fq;
// q = 6 // 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; dist[6 * Np + n] = fq;
// q = 7 // q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (Fx + Fy);
dist[7 * Np + n] = fq; dist[7 * Np + n] = fq;
// q = 8 // 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 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy); 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; dist[8 * Np + n] = fq;
// q = 9 // q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (Fx - Fy);
dist[9 * Np + n] = fq; dist[9 * Np + n] = fq;
// q = 10 // q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (Fx - Fy);
dist[10 * Np + n] = fq; dist[10 * Np + n] = fq;
// q = 11 // q = 11
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8) 0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz); 0.08333333333 * (Fx + Fz);
dist[11 * Np + n] = fq; dist[11 * Np + n] = fq;
// q = 12 // q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 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); mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (Fx + Fz);
dist[12 * Np + n] = fq; dist[12 * Np + n] = fq;
// q = 13 // q = 13
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8) 0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz); 0.08333333333 * (Fx - Fz);
dist[13 * Np + n] = fq; dist[13 * Np + n] = fq;
// q= 14 // q= 14
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4) 0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz); 0.08333333333 * (Fx - Fz);
dist[14 * Np + n] = fq; dist[14 * Np + n] = fq;
// q = 15 // q = 15
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz); 0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
dist[15 * Np + n] = fq; dist[15 * Np + n] = fq;
// q = 16 // q = 16
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz); 0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
dist[16 * Np + n] = fq; dist[16 * Np + n] = fq;
// q = 17 // q = 17
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) 0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz); 0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
dist[17 * Np + n] = fq; dist[17 * Np + n] = fq;
// q = 18 // q = 18
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6) 0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz); 0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
dist[18 * Np + n] = fq; dist[18 * Np + n] = fq;
//........................................................................ //........................................................................
} }
} }
extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB, double Gx, double Gy, double Gz, double rho0, double den_scale, double h, double time_conv,int start, int finish, int Np) extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(
{ int *neighborList, double *dist, double *Velocity, double *ChargeDensity,
double *ElectricField, double rlx_setA, double rlx_setB, double Gx,
double Gy, double Gz, double rho0, double den_scale, double h,
double time_conv, int start, int finish, int Np) {
double fq; double fq;
// conserved momemnts // conserved momemnts
double rho, jx, jy, jz; double rho, jx, jy, jz;
@ -489,9 +514,12 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
Ey = ElectricField[n + 1 * Np]; Ey = ElectricField[n + 1 * Np];
Ez = ElectricField[n + 2 * Np]; Ez = ElectricField[n + 2 * Np];
//compute total body force, including input body force (Gx,Gy,Gz) //compute total body force, including input body force (Gx,Gy,Gz)
Fx = Gx + rhoE*Ex*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale; Fx = Gx + rhoE * Ex * (time_conv * time_conv) / (h * h * 1.0e-12) /
Fy = Gy + rhoE*Ey*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale; den_scale;
Fz = Gz + rhoE*Ez*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale; Fy = Gy + rhoE * Ey * (time_conv * time_conv) / (h * h * 1.0e-12) /
den_scale;
Fz = Gz + rhoE * Ez * (time_conv * time_conv) / (h * h * 1.0e-12) /
den_scale;
// q=0 // q=0
fq = dist[n]; fq = dist[n];
@ -512,7 +540,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
m10 = -4.0 * fq; m10 = -4.0 * fq;
// f2 = dist[10*Np+n]; // 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[nread]; // reading the f2 data into register fq
//fq = dist[Np+n]; //fq = dist[Np+n];
rho += fq; rho += fq;
@ -565,7 +594,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
m11 -= fq; m11 -= fq;
m12 += 2.0 * fq; m12 += 2.0 * fq;
// q = 6 // q = 6
nread = neighborList[n + 5 * Np]; nread = neighborList[n + 5 * Np];
fq = dist[nread]; fq = dist[nread];
@ -810,13 +838,19 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
//..............incorporate external force................................................ //..............incorporate external force................................................
//..............carry out relaxation process............................................... //..............carry out relaxation process...............................................
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho0 - 11*rho) - m1); m1 = m1 +
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho0) - m2); rlx_setA *
((19 * (jx * jx + jy * jy + jz * jz) / rho0 - 11 * rho) - m1);
m2 = m2 +
rlx_setA *
((3 * rho - 5.5 * (jx * jx + jy * jy + jz * jz) / rho0) - m2);
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4); m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6); m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8); m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho0) - m9); m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho0) - 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) / rho0) - m11); m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho0) - m11);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho0) - m12); m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho0) - m12);
m13 = m13 + rlx_setA * ((jx * jy / rho0) - m13); m13 = m13 + rlx_setA * ((jx * jy / rho0) - m13);
@ -833,123 +867,132 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
dist[n] = fq; dist[n] = fq;
// q = 1 // 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]; nread = neighborList[n + Np];
dist[nread] = fq; dist[nread] = fq;
// q=2 // 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]; nread = neighborList[n];
dist[nread] = fq; dist[nread] = fq;
// q = 3 // 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]; nread = neighborList[n + 3 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 4 // 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]; nread = neighborList[n + 2 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 5 // 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]; nread = neighborList[n + 5 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 6 // 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]; nread = neighborList[n + 4 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 7 // q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (Fx + Fy);
nread = neighborList[n + 7 * Np]; nread = neighborList[n + 7 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 8 // 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 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy); 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]; nread = neighborList[n + 6 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 9 // q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (Fx - Fy);
nread = neighborList[n + 9 * Np]; nread = neighborList[n + 9 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 10 // q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11 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); mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (Fx - Fy);
nread = neighborList[n + 8 * Np]; nread = neighborList[n + 8 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 11 // q = 11
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8) 0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz); 0.08333333333 * (Fx + Fz);
nread = neighborList[n + 11 * Np]; nread = neighborList[n + 11 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 12 // q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8) fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 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); mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (Fx + Fz);
nread = neighborList[n + 10 * Np]; nread = neighborList[n + 10 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 13 // q = 13
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8) 0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz); 0.08333333333 * (Fx - Fz);
nread = neighborList[n + 13 * Np]; nread = neighborList[n + 13 * Np];
dist[nread] = fq; dist[nread] = fq;
// q= 14 // q= 14
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4) 0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz); 0.08333333333 * (Fx - Fz);
nread = neighborList[n + 12 * Np]; nread = neighborList[n + 12 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 15 // q = 15
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz); 0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
nread = neighborList[n + 15 * Np]; nread = neighborList[n + 15 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 16 // q = 16
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz); 0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
nread = neighborList[n + 14 * Np]; nread = neighborList[n + 14 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 17 // q = 17
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) 0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz); 0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
nread = neighborList[n + 17 * Np]; nread = neighborList[n + 17 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 18 // q = 18
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6) 0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz); 0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
nread = neighborList[n + 16 * Np]; nread = neighborList[n + 16 * Np];
dist[nread] = fq; dist[nread] = fq;
} }
} }

View File

@ -33,8 +33,10 @@
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
extern "C" void ScaLBL_Gradient_Unpack(double weight, double Cqx, double Cqy, double Cqz, extern "C" void ScaLBL_Gradient_Unpack(double weight, double Cqx, double Cqy,
int *list, int start, int count, double *recvbuf, double *phi, double *grad, int N){ double Cqz, int *list, int start,
int count, double *recvbuf, double *phi,
double *grad, int N) {
//.................................................................................... //....................................................................................
// unpack halo and incorporate into D3Q19 based gradient // unpack halo and incorporate into D3Q19 based gradient
// Distribution q matche Cqx, Cqy, Cqz // Distribution q matche Cqx, Cqy, Cqz
@ -55,16 +57,17 @@ extern "C" void ScaLBL_Gradient_Unpack(double weight, double Cqx, double Cqy, do
} }
} }
extern "C" void ScaLBL_DFH_Init(double *Phi, double *Den, double *Aq, double *Bq, int start, int finish, int Np) extern "C" void ScaLBL_DFH_Init(double *Phi, double *Den, double *Aq,
{ double *Bq, int start, int finish, int Np) {
for (int idx = start; idx < finish; idx++) { for (int idx = start; idx < finish; idx++) {
double phi, nA, nB; double phi, nA, nB;
phi = Phi[idx]; phi = Phi[idx];
if (phi > 0.f) { if (phi > 0.f) {
nA = 1.0; nB = 0.f; nA = 1.0;
} nB = 0.f;
else{ } else {
nB = 1.0; nA = 0.f; nB = 1.0;
nA = 0.f;
} }
Den[idx] = nA; Den[idx] = nA;
Den[Np + idx] = nB; Den[Np + idx] = nB;
@ -87,12 +90,12 @@ extern "C" void ScaLBL_DFH_Init(double *Phi, double *Den, double *Aq, double *Bq
} }
} }
// LBM based on density functional hydrodynamics // LBM based on density functional hydrodynamics
extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double *Aq, double *Bq, double *Den, double *Phi, extern "C" void ScaLBL_D3Q19_AAeven_DFH(
double *Gradient, double *SolidForce, double rhoA, double rhoB, double tauA, double tauB, double alpha, double beta, int *neighborList, double *dist, double *Aq, double *Bq, double *Den,
double Fx, double Fy, double Fz, int start, int finish, int Np) double *Phi, double *Gradient, double *SolidForce, double rhoA, double rhoB,
{ double tauA, double tauB, double alpha, double beta, double Fx, double Fy,
double Fz, int start, int finish, int Np) {
double fq; double fq;
// conserved momemnts // conserved momemnts
double rho, jx, jy, jz; double rho, jx, jy, jz;
@ -118,7 +121,6 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
const double mrt_V11 = 0.01388888888888889; const double mrt_V11 = 0.01388888888888889;
const double mrt_V12 = 0.04166666666666666; const double mrt_V12 = 0.04166666666666666;
for (int n = start; n < finish; n++) { for (int n = start; n < finish; n++) {
// read the component number densities // read the component number densities
@ -140,7 +142,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
ny = Gradient[n + Np]; ny = Gradient[n + Np];
nz = Gradient[n + 2 * Np]; nz = Gradient[n + 2 * Np];
C = sqrt(nx * nx + ny * ny + nz * nz); C = sqrt(nx * nx + ny * ny + nz * nz);
if (C==0.0) C=1.0; if (C == 0.0)
C = 1.0;
nx = nx / C; nx = nx / C;
ny = ny / C; ny = ny / C;
nz = nz / C; nz = nz / C;
@ -418,24 +421,35 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
//........................................................................ //........................................................................
//..............carry out relaxation process.............................. //..............carry out relaxation process..............................
//..........Toelke, Fruediger et. al. 2006................................ //..........Toelke, Fruediger et. al. 2006................................
if (C == 0.0) nx = ny = nz = 0.0; if (C == 0.0)
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho0 - 11*rho) -alpha*C - m1); nx = ny = nz = 0.0;
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho0)- m2); m1 = m1 + rlx_setA *
((19 * (jx * jx + jy * jy + jz * jz) / rho0 - 11 * rho) -
alpha * C - m1);
m2 = m2 +
rlx_setA *
((3 * rho - 5.5 * (jx * jx + jy * jy + jz * jz) / rho0) - m2);
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4); m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6); m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8); m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/rho0) + 0.5*alpha*C*(2*nx*nx-ny*ny-nz*nz) - m9); m9 =
m9 + rlx_setA *
(((2 * jx * jx - jy * jy - jz * jz) / rho0) +
0.5 * alpha * C * (2 * nx * nx - ny * ny - nz * nz) - m9);
m10 = m10 + rlx_setA * (-m10); m10 = m10 + rlx_setA * (-m10);
m11 = m11 + rlx_setA*(((jy*jy-jz*jz)/rho0) + 0.5*alpha*C*(ny*ny-nz*nz)- m11); m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho0) +
0.5 * alpha * C * (ny * ny - nz * nz) - m11);
m12 = m12 + rlx_setA * (-m12); m12 = m12 + rlx_setA * (-m12);
m13 = m13 + rlx_setA*( (jx*jy/rho0) + 0.5*alpha*C*nx*ny - m13); m13 = m13 +
m14 = m14 + rlx_setA*( (jy*jz/rho0) + 0.5*alpha*C*ny*nz - m14); rlx_setA * ((jx * jy / rho0) + 0.5 * alpha * C * nx * ny - m13);
m15 = m15 + rlx_setA*( (jx*jz/rho0) + 0.5*alpha*C*nx*nz - m15); m14 = m14 +
rlx_setA * ((jy * jz / rho0) + 0.5 * alpha * C * ny * nz - m14);
m15 = m15 +
rlx_setA * ((jx * jz / rho0) + 0.5 * alpha * C * nx * nz - m15);
m16 = m16 + rlx_setB * (-m16); m16 = m16 + rlx_setB * (-m16);
m17 = m17 + rlx_setB * (-m17); m17 = m17 + rlx_setB * (-m17);
m18 = m18 + rlx_setB * (-m18); m18 = m18 + rlx_setB * (-m18);
//....................................................................................................... //.......................................................................................................
// assign force with wetting BC // assign force with wetting BC
force_x = alpha * (nA - nB) * SolidForce[n] + Fx; force_x = alpha * (nA - nB) * SolidForce[n] + Fx;
@ -448,101 +462,114 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
dist[n] = fq; dist[n] = fq;
// q = 1 // q = 1
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10) + 0.16666666*force_x; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jx - m4) +
mrt_V6 * (m9 - m10) + 0.16666666 * force_x;
dist[1 * Np + n] = fq; dist[1 * Np + n] = fq;
// q=2 // q=2
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10) - 0.16666666*force_x; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m4 - jx) +
mrt_V6 * (m9 - m10) - 0.16666666 * force_x;
dist[2 * Np + n] = fq; dist[2 * Np + n] = fq;
// q = 3 // 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*force_y; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jy - m6) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) + 0.16666666 * force_y;
dist[3 * Np + n] = fq; dist[3 * Np + n] = fq;
// q = 4 // 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*force_y; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m6 - jy) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) - 0.16666666 * force_y;
dist[4 * Np + n] = fq; dist[4 * Np + n] = fq;
// q = 5 // 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*force_z; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jz - m8) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) + 0.16666666 * force_z;
dist[5 * Np + n] = fq; dist[5 * Np + n] = fq;
// q = 6 // 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*force_z; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m8 - jz) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) - 0.16666666 * force_z;
dist[6 * Np + n] = fq; dist[6 * Np + n] = fq;
// q = 7 // q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)+ fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(force_x+force_y); 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 * (force_x + force_y);
dist[7 * Np + n] = fq; dist[7 * Np + n] = fq;
// q = 8 // 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 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(force_x+force_y); 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 * (force_x + force_y);
dist[8 * Np + n] = fq; dist[8 * Np + n] = fq;
// q = 9 // q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)+ fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(force_x-force_y); 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 * (force_x - force_y);
dist[9 * Np + n] = fq; dist[9 * Np + n] = fq;
// q = 10 // q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)+ fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(force_x-force_y); 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 * (force_x - force_y);
dist[10 * Np + n] = fq; dist[10 * Np + n] = fq;
// q = 11 // q = 11
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8) 0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(force_x+force_z); 0.08333333333 * (force_x + force_z);
dist[11 * Np + n] = fq; dist[11 * Np + n] = fq;
// q = 12 // q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)+ fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
mrt_V7*m9+mrt_V11*m10-mrt_V8*m11-mrt_V12*m12+0.25*m15+0.125*(m16-m18)-0.08333333333*(force_x+force_z); 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 * (force_x + force_z);
dist[12 * Np + n] = fq; dist[12 * Np + n] = fq;
// q = 13 // q = 13
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8) 0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(force_x-force_z); 0.08333333333 * (force_x - force_z);
dist[13 * Np + n] = fq; dist[13 * Np + n] = fq;
// q= 14 // q= 14
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4) 0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(force_x-force_z); 0.08333333333 * (force_x - force_z);
dist[14 * Np + n] = fq; dist[14 * Np + n] = fq;
// q = 15 // q = 15
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(force_y+force_z); 0.125 * (m17 - m18) + 0.08333333333 * (force_y + force_z);
dist[15 * Np + n] = fq; dist[15 * Np + n] = fq;
// q = 16 // q = 16
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(force_y+force_z); 0.125 * (m18 - m17) - 0.08333333333 * (force_y + force_z);
dist[16 * Np + n] = fq; dist[16 * Np + n] = fq;
// q = 17 // q = 17
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) 0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(force_y-force_z); 0.125 * (m17 + m18) + 0.08333333333 * (force_y - force_z);
dist[17 * Np + n] = fq; dist[17 * Np + n] = fq;
// q = 18 // q = 18
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6) 0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(force_y-force_z); 0.125 * (m17 + m18) - 0.08333333333 * (force_y - force_z);
dist[18 * Np + n] = fq; dist[18 * Np + n] = fq;
//........................................................................ //........................................................................
@ -566,7 +593,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
// q = 0,2,4 // q = 0,2,4
// Cq = {1,0,0}, {0,1,0}, {0,0,1} // Cq = {1,0,0}, {0,1,0}, {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nx; 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; a1 = nA * (0.1111111111111111 * (1 + 4.5 * ux)) + delta;
b1 = nB * (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; a2 = nA * (0.1111111111111111 * (1 - 4.5 * ux)) - delta;
@ -581,7 +609,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
// q = 2 // q = 2
// Cq = {0,1,0} // Cq = {0,1,0}
delta = beta * nA * nB * nAB * 0.1111111111111111 * ny; delta = beta * nA * nB * nAB * 0.1111111111111111 * ny;
if (!(nA*nB*nAB>0)) delta=0; if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (0.1111111111111111 * (1 + 4.5 * uy)) + delta; a1 = nA * (0.1111111111111111 * (1 + 4.5 * uy)) + delta;
b1 = nB * (0.1111111111111111 * (1 + 4.5 * uy)) - delta; b1 = nB * (0.1111111111111111 * (1 + 4.5 * uy)) - delta;
a2 = nA * (0.1111111111111111 * (1 - 4.5 * uy)) - delta; a2 = nA * (0.1111111111111111 * (1 - 4.5 * uy)) - delta;
@ -595,7 +624,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
// q = 4 // q = 4
// Cq = {0,0,1} // Cq = {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nz; delta = beta * nA * nB * nAB * 0.1111111111111111 * nz;
if (!(nA*nB*nAB>0)) delta=0; if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (0.1111111111111111 * (1 + 4.5 * uz)) + delta; a1 = nA * (0.1111111111111111 * (1 + 4.5 * uz)) + delta;
b1 = nB * (0.1111111111111111 * (1 + 4.5 * uz)) - delta; b1 = nB * (0.1111111111111111 * (1 + 4.5 * uz)) - delta;
a2 = nA * (0.1111111111111111 * (1 - 4.5 * uz)) - delta; a2 = nA * (0.1111111111111111 * (1 - 4.5 * uz)) - delta;
@ -606,14 +636,14 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
Aq[6 * Np + n] = a2; Aq[6 * Np + n] = a2;
Bq[6 * Np + n] = b2; Bq[6 * Np + n] = b2;
//............................................... //...............................................
}
} }
} extern "C" void ScaLBL_D3Q19_AAodd_DFH(
int *neighborList, double *dist, double *Aq, double *Bq, double *Den,
extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *Aq, double *Bq, double *Den, double *Phi, double *Gradient, double *SolidForce, double rhoA, double rhoB,
double *Phi, double *Gradient, double *SolidForce, double rhoA, double rhoB, double tauA, double tauB, double alpha, double beta, double tauA, double tauB, double alpha, double beta, double Fx, double Fy,
double Fx, double Fy, double Fz, int start, int finish, int Np){ double Fz, int start, int finish, int Np) {
int nread; int nread;
int nr1, nr2, nr3, nr4, nr5, nr6; int nr1, nr2, nr3, nr4, nr5, nr6;
@ -666,7 +696,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
ny = Gradient[n + Np]; ny = Gradient[n + Np];
nz = Gradient[n + 2 * Np]; nz = Gradient[n + 2 * Np];
C = sqrt(nx * nx + ny * ny + nz * nz); C = sqrt(nx * nx + ny * ny + nz * nz);
if (C==0.0) C=1.0; if (C == 0.0)
C = 1.0;
nx = nx / C; nx = nx / C;
ny = ny / C; ny = ny / C;
nz = nz / C; nz = nz / C;
@ -748,7 +779,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
m11 -= fq; m11 -= fq;
m12 += 2.0 * fq; m12 += 2.0 * fq;
// q = 6 // q = 6
//nread = neighborList[n+5*Np]; //nread = neighborList[n+5*Np];
//fq = dist[nread]; //fq = dist[nread];
@ -995,19 +1025,31 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
//........................................................................ //........................................................................
//..............carry out relaxation process.............................. //..............carry out relaxation process..............................
//..........Toelke, Fruediger et. al. 2006................................ //..........Toelke, Fruediger et. al. 2006................................
if (C == 0.0) nx = ny = nz = 0.0; if (C == 0.0)
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho0 - 11*rho) -alpha*C - m1); nx = ny = nz = 0.0;
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho0)- m2); m1 = m1 + rlx_setA *
((19 * (jx * jx + jy * jy + jz * jz) / rho0 - 11 * rho) -
alpha * C - m1);
m2 = m2 +
rlx_setA *
((3 * rho - 5.5 * (jx * jx + jy * jy + jz * jz) / rho0) - m2);
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4); m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6); m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8); m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/rho0) + 0.5*alpha*C*(2*nx*nx-ny*ny-nz*nz) - m9); m9 =
m9 + rlx_setA *
(((2 * jx * jx - jy * jy - jz * jz) / rho0) +
0.5 * alpha * C * (2 * nx * nx - ny * ny - nz * nz) - m9);
m10 = m10 + rlx_setA * (-m10); m10 = m10 + rlx_setA * (-m10);
m11 = m11 + rlx_setA*(((jy*jy-jz*jz)/rho0) + 0.5*alpha*C*(ny*ny-nz*nz)- m11); m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho0) +
0.5 * alpha * C * (ny * ny - nz * nz) - m11);
m12 = m12 + rlx_setA * (-m12); m12 = m12 + rlx_setA * (-m12);
m13 = m13 + rlx_setA*( (jx*jy/rho0) + 0.5*alpha*C*nx*ny - m13); m13 = m13 +
m14 = m14 + rlx_setA*( (jy*jz/rho0) + 0.5*alpha*C*ny*nz - m14); rlx_setA * ((jx * jy / rho0) + 0.5 * alpha * C * nx * ny - m13);
m15 = m15 + rlx_setA*( (jx*jz/rho0) + 0.5*alpha*C*nx*nz - m15); m14 = m14 +
rlx_setA * ((jy * jz / rho0) + 0.5 * alpha * C * ny * nz - m14);
m15 = m15 +
rlx_setA * ((jx * jz / rho0) + 0.5 * alpha * C * nx * nz - m15);
m16 = m16 + rlx_setB * (-m16); m16 = m16 + rlx_setB * (-m16);
m17 = m17 + rlx_setB * (-m17); m17 = m17 + rlx_setB * (-m17);
m18 = m18 + rlx_setB * (-m18); m18 = m18 + rlx_setB * (-m18);
@ -1023,116 +1065,130 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
dist[n] = fq; dist[n] = fq;
// q = 1 // q = 1
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10)+0.16666666*force_x; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jx - m4) +
mrt_V6 * (m9 - m10) + 0.16666666 * force_x;
//nread = neighborList[n+Np]; //nread = neighborList[n+Np];
dist[nr2] = fq; dist[nr2] = fq;
// q=2 // q=2
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10) - 0.16666666*force_x; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m4 - jx) +
mrt_V6 * (m9 - m10) - 0.16666666 * force_x;
//nread = neighborList[n]; //nread = neighborList[n];
dist[nr1] = fq; dist[nr1] = fq;
// q = 3 // 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*force_y; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jy - m6) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) + 0.16666666 * force_y;
//nread = neighborList[n+3*Np]; //nread = neighborList[n+3*Np];
dist[nr4] = fq; dist[nr4] = fq;
// q = 4 // 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*force_y; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m6 - jy) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) - 0.16666666 * force_y;
//nread = neighborList[n+2*Np]; //nread = neighborList[n+2*Np];
dist[nr3] = fq; dist[nr3] = fq;
// q = 5 // 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*force_z; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jz - m8) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) + 0.16666666 * force_z;
//nread = neighborList[n+5*Np]; //nread = neighborList[n+5*Np];
dist[nr6] = fq; dist[nr6] = fq;
// q = 6 // 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*force_z; fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m8 - jz) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) - 0.16666666 * force_z;
//nread = neighborList[n+4*Np]; //nread = neighborList[n+4*Np];
dist[nr5] = fq; dist[nr5] = fq;
// q = 7 // q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)+ fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(force_x+force_y); 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 * (force_x + force_y);
//nread = neighborList[n+7*Np]; //nread = neighborList[n+7*Np];
dist[nr8] = fq; dist[nr8] = fq;
// q = 8 // 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 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(force_x+force_y); 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 * (force_x + force_y);
//nread = neighborList[n+6*Np]; //nread = neighborList[n+6*Np];
dist[nr7] = fq; dist[nr7] = fq;
// q = 9 // q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)+ fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(force_x-force_y); 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 * (force_x - force_y);
//nread = neighborList[n+9*Np]; //nread = neighborList[n+9*Np];
dist[nr10] = fq; dist[nr10] = fq;
// q = 10 // q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)+ fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(force_x-force_y); 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 * (force_x - force_y);
//nread = neighborList[n+8*Np]; //nread = neighborList[n+8*Np];
dist[nr9] = fq; dist[nr9] = fq;
// q = 11 // q = 11
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8) 0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(force_x+force_z); 0.08333333333 * (force_x + force_z);
//nread = neighborList[n+11*Np]; //nread = neighborList[n+11*Np];
dist[nr12] = fq; dist[nr12] = fq;
// q = 12 // q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)+ fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
mrt_V7*m9+mrt_V11*m10-mrt_V8*m11-mrt_V12*m12+0.25*m15+0.125*(m16-m18) - 0.08333333333*(force_x+force_z); 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 * (force_x + force_z);
//nread = neighborList[n+10*Np]; //nread = neighborList[n+10*Np];
dist[nr11] = fq; dist[nr11] = fq;
// q = 13 // q = 13
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8) 0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(force_x-force_z); 0.08333333333 * (force_x - force_z);
//nread = neighborList[n+13*Np]; //nread = neighborList[n+13*Np];
dist[nr14] = fq; dist[nr14] = fq;
// q= 14 // q= 14
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4) 0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11 mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(force_x-force_z); 0.08333333333 * (force_x - force_z);
//nread = neighborList[n+12*Np]; //nread = neighborList[n+12*Np];
dist[nr13] = fq; dist[nr13] = fq;
// q = 15 // q = 15
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(force_y+force_z); 0.125 * (m17 - m18) + 0.08333333333 * (force_y + force_z);
nread = neighborList[n + 15 * Np]; nread = neighborList[n + 15 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 16 // q = 16
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8) 0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(force_y+force_z); 0.125 * (m18 - m17) - 0.08333333333 * (force_y + force_z);
nread = neighborList[n + 14 * Np]; nread = neighborList[n + 14 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 17 // q = 17
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8) 0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(force_y-force_z); 0.125 * (m17 + m18) + 0.08333333333 * (force_y - force_z);
nread = neighborList[n + 17 * Np]; nread = neighborList[n + 17 * Np];
dist[nread] = fq; dist[nread] = fq;
// q = 18 // q = 18
fq = mrt_V1*rho+mrt_V9*m1 fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6) 0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(force_y-force_z); 0.125 * (m17 + m18) - 0.08333333333 * (force_y - force_z);
nread = neighborList[n + 16 * Np]; nread = neighborList[n + 16 * Np];
dist[nread] = fq; dist[nread] = fq;
@ -1154,7 +1210,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
// q = 0,2,4 // q = 0,2,4
// Cq = {1,0,0}, {0,1,0}, {0,0,1} // Cq = {1,0,0}, {0,1,0}, {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nx; 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; a1 = nA * (0.1111111111111111 * (1 + 4.5 * ux)) + delta;
b1 = nB * (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; a2 = nA * (0.1111111111111111 * (1 - 4.5 * ux)) - delta;
@ -1172,7 +1229,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
//............................................... //...............................................
// Cq = {0,1,0} // Cq = {0,1,0}
delta = beta * nA * nB * nAB * 0.1111111111111111 * ny; delta = beta * nA * nB * nAB * 0.1111111111111111 * ny;
if (!(nA*nB*nAB>0)) delta=0; if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (0.1111111111111111 * (1 + 4.5 * uy)) + delta; a1 = nA * (0.1111111111111111 * (1 + 4.5 * uy)) + delta;
b1 = nB * (0.1111111111111111 * (1 + 4.5 * uy)) - delta; b1 = nB * (0.1111111111111111 * (1 + 4.5 * uy)) - delta;
a2 = nA * (0.1111111111111111 * (1 - 4.5 * uy)) - delta; a2 = nA * (0.1111111111111111 * (1 - 4.5 * uy)) - delta;
@ -1191,7 +1249,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
// q = 4 // q = 4
// Cq = {0,0,1} // Cq = {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nz; delta = beta * nA * nB * nAB * 0.1111111111111111 * nz;
if (!(nA*nB*nAB>0)) delta=0; if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (0.1111111111111111 * (1 + 4.5 * uz)) + delta; a1 = nA * (0.1111111111111111 * (1 + 4.5 * uz)) + delta;
b1 = nB * (0.1111111111111111 * (1 + 4.5 * uz)) - delta; b1 = nB * (0.1111111111111111 * (1 + 4.5 * uz)) - delta;
a2 = nA * (0.1111111111111111 * (1 - 4.5 * uz)) - delta; a2 = nA * (0.1111111111111111 * (1 - 4.5 * uz)) - delta;
@ -1210,8 +1269,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
} }
extern "C" void ScaLBL_D3Q7_AAodd_DFH(int *neighborList, double *Aq, double *Bq, extern "C" void ScaLBL_D3Q7_AAodd_DFH(int *neighborList, double *Aq, double *Bq,
double *Den, double *Phi, int start, int finish, int Np) double *Den, double *Phi, int start,
{ int finish, int Np) {
for (int n = start; n < finish; n++) { for (int n = start; n < finish; n++) {
int nread; int nread;
@ -1297,9 +1356,9 @@ extern "C" void ScaLBL_D3Q7_AAodd_DFH(int *neighborList, double *Aq, double *Bq,
} }
} }
extern "C" void ScaLBL_D3Q7_AAeven_DFH(double *Aq, double *Bq, double *Den, double *Phi, extern "C" void ScaLBL_D3Q7_AAeven_DFH(double *Aq, double *Bq, double *Den,
int start, int finish, int Np) double *Phi, int start, int finish,
{ int Np) {
for (int n = start; n < finish; n++) { for (int n = start; n < finish; n++) {
double fq, nA, nB; double fq, nA, nB;
// compute number density for component A // compute number density for component A
@ -1370,7 +1429,9 @@ extern "C" void ScaLBL_D3Q7_AAeven_DFH(double *Aq, double *Bq, double *Den, doub
} }
} }
extern "C" void ScaLBL_D3Q19_Gradient_DFH(int *neighborList, double *Phi, double *ColorGrad, int start, int finish, int Np){ extern "C" void ScaLBL_D3Q19_Gradient_DFH(int *neighborList, double *Phi,
double *ColorGrad, int start,
int finish, int Np) {
int n, nn; int n, nn;
// distributions // distributions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,3 @@
*/ */
// cpu implementation for thermal lattice boltzmann methods // cpu implementation for thermal lattice boltzmann methods
// copyright James McClure, 2014 // copyright James McClure, 2014

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,6 @@ Implementation of color lattice boltzmann model
#include "ProfilerApp.h" #include "ProfilerApp.h"
#include "threadpool/thread_pool.h" #include "threadpool/thread_pool.h"
#ifndef ScaLBL_ColorModel_INC #ifndef ScaLBL_ColorModel_INC
#define ScaLBL_ColorModel_INC #define ScaLBL_ColorModel_INC
@ -166,4 +165,3 @@ private:
}; };
#endif #endif

View File

@ -3,16 +3,13 @@ color lattice boltzmann model
*/ */
#include "models/DFHModel.h" #include "models/DFHModel.h"
ScaLBL_DFHModel::ScaLBL_DFHModel(int RANK, int NP, const Utilities::MPI& COMM): ScaLBL_DFHModel::ScaLBL_DFHModel(int RANK, int NP, const Utilities::MPI &COMM)
rank(RANK), nprocs(NP), Restart(0),timestep(0),timestepMax(0),tauA(0),tauB(0),rhoA(0),rhoB(0),alpha(0),beta(0), : rank(RANK), nprocs(NP), Restart(0), timestep(0), timestepMax(0), tauA(0),
Fx(0),Fy(0),Fz(0),flux(0),din(0),dout(0),inletA(0),inletB(0),outletA(0),outletB(0), tauB(0), rhoA(0), rhoB(0), alpha(0), beta(0), Fx(0), Fy(0), Fz(0),
Nx(0),Ny(0),Nz(0),N(0),Np(0),nprocx(0),nprocy(0),nprocz(0),BoundaryCondition(0),Lx(0),Ly(0),Lz(0),comm(COMM) flux(0), din(0), dout(0), inletA(0), inletB(0), outletA(0), outletB(0),
{ Nx(0), Ny(0), Nz(0), N(0), Np(0), nprocx(0), nprocy(0), nprocz(0),
BoundaryCondition(0), Lx(0), Ly(0), Lz(0), comm(COMM) {}
} ScaLBL_DFHModel::~ScaLBL_DFHModel() {}
ScaLBL_DFHModel::~ScaLBL_DFHModel(){
}
/*void ScaLBL_DFHModel::WriteCheckpoint(const char *FILENAME, const double *cPhi, const double *cfq, int Np) /*void ScaLBL_DFHModel::WriteCheckpoint(const char *FILENAME, const double *cPhi, const double *cfq, int Np)
{ {
@ -51,7 +48,6 @@ void ScaLBL_DFHModel::ReadCheckpoint(char *FILENAME, double *cPhi, double *cfq,
} }
*/ */
void ScaLBL_DFHModel::ReadParams(string filename) { void ScaLBL_DFHModel::ReadParams(string filename) {
// read the input database // read the input database
db = std::make_shared<Database>(filename); db = std::make_shared<Database>(filename);
@ -84,8 +80,7 @@ void ScaLBL_DFHModel::ReadParams(string filename){
BoundaryCondition = domain_db->getScalar<int>("BC"); BoundaryCondition = domain_db->getScalar<int>("BC");
if (color_db->keyExists("BC")) { if (color_db->keyExists("BC")) {
BoundaryCondition = color_db->getScalar<int>("BC"); BoundaryCondition = color_db->getScalar<int>("BC");
} } else if (domain_db->keyExists("BC")) {
else if (domain_db->keyExists( "BC" )){
BoundaryCondition = domain_db->getScalar<int>("BC"); BoundaryCondition = domain_db->getScalar<int>("BC");
} }
@ -103,17 +98,25 @@ void ScaLBL_DFHModel::ReadParams(string filename){
nprocy = nproc[1]; nprocy = nproc[1];
nprocz = nproc[2]; nprocz = nproc[2];
if (BoundaryCondition==4) flux = din*rhoA; // mass flux must adjust for density (see formulation for details) if (BoundaryCondition == 4)
flux =
din *
rhoA; // mass flux must adjust for density (see formulation for details)
} }
void ScaLBL_DFHModel::SetDomain() { void ScaLBL_DFHModel::SetDomain() {
Dm = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // full domain for analysis Dm = std::shared_ptr<Domain>(
Mask = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // mask domain removes immobile phases new Domain(domain_db, comm)); // full domain for analysis
Nx+=2; Ny+=2; Nz += 2; Mask = std::shared_ptr<Domain>(
new Domain(domain_db, comm)); // mask domain removes immobile phases
Nx += 2;
Ny += 2;
Nz += 2;
N = Nx * Ny * Nz; N = Nx * Ny * Nz;
id = new char[N]; id = new char[N];
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = 1; // initialize this way for (int i = 0; i < Nx * Ny * Nz; i++)
Averages = std::shared_ptr<TwoPhase> ( new TwoPhase(Dm) ); // TwoPhase analysis object Dm->id[i] = 1; // initialize this way
Averages =
std::shared_ptr<TwoPhase>(new TwoPhase(Dm)); // TwoPhase analysis object
comm.barrier(); comm.barrier();
Dm->CommInit(); Dm->CommInit();
comm.barrier(); comm.barrier();
@ -122,10 +125,12 @@ void ScaLBL_DFHModel::SetDomain(){
void ScaLBL_DFHModel::ReadInput() { void ScaLBL_DFHModel::ReadInput() {
//....................................................................... //.......................................................................
if (rank == 0) printf("Read input media... \n"); if (rank == 0)
printf("Read input media... \n");
//....................................................................... //.......................................................................
Mask->ReadIDs(); Mask->ReadIDs();
for (int i=0; i<Nx*Ny*Nz; i++) id[i] = Mask->id[i]; // save what was read for (int i = 0; i < Nx * Ny * Nz; i++)
id[i] = Mask->id[i]; // save what was read
sprintf(LocalRankString, "%05d", rank); sprintf(LocalRankString, "%05d", rank);
sprintf(LocalRankFilename, "%s%s", "ID.", LocalRankString); sprintf(LocalRankFilename, "%s%s", "ID.", LocalRankString);
@ -133,17 +138,18 @@ void ScaLBL_DFHModel::ReadInput(){
// .......... READ THE INPUT FILE ....................................... // .......... READ THE INPUT FILE .......................................
//........................................................................... //...........................................................................
if (rank == 0) cout << "Reading in signed distance function..." << endl; if (rank == 0)
cout << "Reading in signed distance function..." << endl;
//....................................................................... //.......................................................................
sprintf(LocalRankString, "%05d", rank); sprintf(LocalRankString, "%05d", rank);
sprintf(LocalRankFilename, "%s%s", "SignDist.", LocalRankString); sprintf(LocalRankFilename, "%s%s", "SignDist.", LocalRankString);
ReadBinaryFile(LocalRankFilename, Averages->SDs.data(), N); ReadBinaryFile(LocalRankFilename, Averages->SDs.data(), N);
comm.barrier(); comm.barrier();
if (rank == 0) cout << "Domain set." << endl; if (rank == 0)
cout << "Domain set." << endl;
} }
void ScaLBL_DFHModel::AssignComponentLabels(double *phase) void ScaLBL_DFHModel::AssignComponentLabels(double *phase) {
{
size_t NLABELS = 0; size_t NLABELS = 0;
char VALUE = 0; char VALUE = 0;
double AFFINITY = 0.f; double AFFINITY = 0.f;
@ -153,7 +159,8 @@ void ScaLBL_DFHModel::AssignComponentLabels(double *phase)
NLABELS = LabelList.size(); NLABELS = LabelList.size();
if (NLABELS != AffinityList.size()) { if (NLABELS != AffinityList.size()) {
ERROR("Error: ComponentLabels and ComponentAffinity must be the same length! \n"); ERROR("Error: ComponentLabels and ComponentAffinity must be the same "
"length! \n");
} }
if (rank == 0) { if (rank == 0) {
@ -176,7 +183,8 @@ void ScaLBL_DFHModel::AssignComponentLabels(double *phase)
if (VALUE == LabelList[idx]) { if (VALUE == LabelList[idx]) {
AFFINITY = AffinityList[idx]; AFFINITY = AffinityList[idx];
idx = NLABELS; idx = NLABELS;
Mask->id[n] = 0; // set mask to zero since this is an immobile component Mask->id[n] =
0; // set mask to zero since this is an immobile component
} }
} }
phase[n] = AFFINITY; phase[n] = AFFINITY;
@ -184,10 +192,10 @@ void ScaLBL_DFHModel::AssignComponentLabels(double *phase)
} }
} }
// Set Dm to match Mask // Set Dm to match Mask
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
} }
void ScaLBL_DFHModel::Create() { void ScaLBL_DFHModel::Create() {
/* /*
* This function creates the variables needed to run a LBM * This function creates the variables needed to run a LBM
@ -199,26 +207,33 @@ void ScaLBL_DFHModel::Create(){
//......................................................... //.........................................................
// Initialize communication structures in averaging domain // Initialize communication structures in averaging domain
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
Mask->CommInit(); Mask->CommInit();
Np = Mask->PoreCount(); Np = Mask->PoreCount();
//........................................................................... //...........................................................................
if (rank==0) printf ("Create ScaLBL_Communicator \n"); if (rank == 0)
printf("Create ScaLBL_Communicator \n");
// Create a communicator for the device (will use optimized layout) // Create a communicator for the device (will use optimized layout)
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original // ScaLBL_Communicator ScaLBL_Comm(Mask); // original
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask)); ScaLBL_Comm =
std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
int Npad = (Np / 16 + 2) * 16; int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N); if (rank == 0)
Map.resize(Nx,Ny,Nz); Map.fill(-2); printf("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx, Ny, Nz);
Map.fill(-2);
auto neighborList = new int[18 * Npad]; auto neighborList = new int[18 * Npad];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1); Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 1);
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
//........................................................................... //...........................................................................
// MAIN VARIABLES ALLOCATED HERE // MAIN VARIABLES ALLOCATED HERE
//........................................................................... //...........................................................................
// LBM variables // LBM variables
if (rank==0) printf ("Allocating distributions \n"); if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions................................. //......................device distributions.................................
dist_mem_size = Np * sizeof(double); dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int)); neighborSize = 18 * (Np * sizeof(int));
@ -234,11 +249,13 @@ void ScaLBL_DFHModel::Create(){
ScaLBL_AllocateDeviceMemory((void **)&Pressure, sizeof(double) * Np); ScaLBL_AllocateDeviceMemory((void **)&Pressure, sizeof(double) * Np);
ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np); ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np);
ScaLBL_AllocateDeviceMemory((void **)&Gradient, 3 * sizeof(double) * Np); ScaLBL_AllocateDeviceMemory((void **)&Gradient, 3 * sizeof(double) * Np);
ScaLBL_AllocateDeviceMemory((void **) &SolidPotential, 3*sizeof(double)*Np); ScaLBL_AllocateDeviceMemory((void **)&SolidPotential,
3 * sizeof(double) * Np);
//........................................................................... //...........................................................................
// Update GPU data structures // Update GPU data structures
if (rank==0) printf ("Setting up device map and neighbor list \n"); if (rank == 0)
printf("Setting up device map and neighbor list \n");
// copy the neighbor list // copy the neighbor list
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize); ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
@ -262,7 +279,8 @@ void ScaLBL_DFHModel::Create(){
* AssignComponentLabels * * AssignComponentLabels *
********************************************************/ ********************************************************/
void ScaLBL_DFHModel::AssignSolidPotential() { void ScaLBL_DFHModel::AssignSolidPotential() {
if (rank==0) printf("Computing solid interaction potential (Shan-Chen type) \n"); if (rank == 0)
printf("Computing solid interaction potential (Shan-Chen type) \n");
double *PhaseLabel; double *PhaseLabel;
PhaseLabel = new double[Nx * Ny * Nz]; PhaseLabel = new double[Nx * Ny * Nz];
AssignComponentLabels(PhaseLabel); AssignComponentLabels(PhaseLabel);
@ -277,7 +295,9 @@ void ScaLBL_DFHModel::AssignSolidPotential(){
for (int jj = 0; jj < 3; jj++) { for (int jj = 0; jj < 3; jj++) {
for (int ii = 0; ii < 3; ii++) { for (int ii = 0; ii < 3; ii++) {
int index = kk * 9 + jj * 3 + ii; int index = kk * 9 + jj * 3 + ii;
Dst[index] = sqrt(double(ii-1)*double(ii-1) + double(jj-1)*double(jj-1)+ double(kk-1)*double(kk-1)); Dst[index] = sqrt(double(ii - 1) * double(ii - 1) +
double(jj - 1) * double(jj - 1) +
double(kk - 1) * double(kk - 1));
} }
} }
} }
@ -336,12 +356,18 @@ void ScaLBL_DFHModel::AssignSolidPotential(){
int idj = j + jj - 1; int idj = j + jj - 1;
int idk = k + kk - 1; int idk = k + kk - 1;
if (idi < 0) idi=0; if (idi < 0)
if (idj < 0) idj=0; idi = 0;
if (idk < 0) idk=0; if (idj < 0)
if (!(idi < Nx)) idi=Nx-1; idj = 0;
if (!(idj < Ny)) idj=Ny-1; if (idk < 0)
if (!(idk < Nz)) idk=Nz-1; idk = 0;
if (!(idi < Nx))
idi = Nx - 1;
if (!(idj < Ny))
idj = Ny - 1;
if (!(idk < Nz))
idk = Nz - 1;
int nn = idk * Nx * Ny + idj * Nx + idi; int nn = idk * Nx * Ny + idj * Nx + idi;
if (!(Mask->id[nn] > 0)) { if (!(Mask->id[nn] > 0)) {
@ -432,12 +458,15 @@ void ScaLBL_DFHModel::Initialize(){
} }
count_wet_global = Dm->Comm.sumReduce(count_wet); count_wet_global = Dm->Comm.sumReduce(count_wet);
if (rank==0) printf("Wetting phase volume fraction =%f \n",count_wet_global/double(Nx*Ny*Nz*nprocs)); if (rank == 0)
printf("Wetting phase volume fraction =%f \n",
count_wet_global / double(Nx * Ny * Nz * nprocs));
// initialize phi based on PhaseLabel (include solid component labels) // initialize phi based on PhaseLabel (include solid component labels)
ScaLBL_CopyToDevice(Phi, PhaseLabel, Np * sizeof(double)); ScaLBL_CopyToDevice(Phi, PhaseLabel, Np * sizeof(double));
//........................................................................... //...........................................................................
if (rank==0) printf ("Initializing distributions \n"); if (rank == 0)
printf("Initializing distributions \n");
ScaLBL_D3Q19_Init(fq, Np); ScaLBL_D3Q19_Init(fq, Np);
if (Restart == true) { if (Restart == true) {
@ -447,8 +476,7 @@ void ScaLBL_DFHModel::Initialize(){
if (restart.is_open()) { if (restart.is_open()) {
restart >> timestep; restart >> timestep;
printf("Restarting from timestep =%i \n", timestep); printf("Restarting from timestep =%i \n", timestep);
} } else {
else{
printf("WARNING:No Restart.txt file, setting timestep=0 \n"); printf("WARNING:No Restart.txt file, setting timestep=0 \n");
timestep = 0; timestep = 0;
} }
@ -478,25 +506,29 @@ void ScaLBL_DFHModel::Initialize(){
comm.barrier(); comm.barrier();
} }
if (rank==0) printf ("Initializing phase field \n"); if (rank == 0)
printf("Initializing phase field \n");
ScaLBL_DFH_Init(Phi, Den, Aq, Bq, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_DFH_Init(Phi, Den, Aq, Bq, 0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_DFH_Init(Phi, Den, Aq, Bq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_DFH_Init(Phi, Den, Aq, Bq, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
} }
void ScaLBL_DFHModel::Run() { void ScaLBL_DFHModel::Run() {
int nprocs = nprocx * nprocy * nprocz; int nprocs = nprocx * nprocy * nprocz;
const RankInfoStruct rank_info(rank, nprocx, nprocy, nprocz); const RankInfoStruct rank_info(rank, nprocx, nprocy, nprocz);
if (rank==0) printf("********************************************************\n"); if (rank == 0)
if (rank==0) printf("No. of timesteps: %i \n", timestepMax); printf("********************************************************\n");
if (rank == 0)
printf("No. of timesteps: %i \n", timestepMax);
ScaLBL_DeviceBarrier(); ScaLBL_DeviceBarrier();
comm.barrier(); comm.barrier();
//************ MAIN ITERATION LOOP ***************************************/ //************ MAIN ITERATION LOOP ***************************************/
auto t1 = std::chrono::system_clock::now(); auto t1 = std::chrono::system_clock::now();
bool Regular = true; bool Regular = true;
PROFILE_START("Loop"); PROFILE_START("Loop");
runAnalysis analysis( analysis_db, rank_info, ScaLBL_Comm, Dm, Np, Regular, Map ); runAnalysis analysis(analysis_db, rank_info, ScaLBL_Comm, Dm, Np, Regular,
Map);
while (timestep < timestepMax) { while (timestep < timestepMax) {
//if ( rank==0 ) { printf("Running timestep %i (%i MB)\n",timestep+1,(int)(Utilities::getMemoryUsage()/1048576)); } //if ( rank==0 ) { printf("Running timestep %i (%i MB)\n",timestep+1,(int)(Utilities::getMemoryUsage()/1048576)); }
PROFILE_START("Update"); PROFILE_START("Update");
@ -505,20 +537,28 @@ void ScaLBL_DFHModel::Run(){
// Compute the Phase indicator field // Compute the Phase indicator field
// Read for Aq, Bq happens in this routine (requires communication) // Read for Aq, Bq happens in this routine (requires communication)
ScaLBL_Comm->BiSendD3Q7AA(Aq, Bq); //READ FROM NORMAL ScaLBL_Comm->BiSendD3Q7AA(Aq, Bq); //READ FROM NORMAL
ScaLBL_D3Q7_AAodd_DFH(NeighborList, Aq, Bq, Den, Phi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_D3Q7_AAodd_DFH(NeighborList, Aq, Bq, Den, Phi,
ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->BiRecvD3Q7AA(Aq, Bq); //WRITE INTO OPPOSITE ScaLBL_Comm->BiRecvD3Q7AA(Aq, Bq); //WRITE INTO OPPOSITE
ScaLBL_D3Q7_AAodd_DFH(NeighborList, Aq, Bq, Den, Phi, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_D3Q7_AAodd_DFH(NeighborList, Aq, Bq, Den, Phi, 0,
ScaLBL_Comm->LastExterior(), Np);
// compute the gradient // compute the gradient
ScaLBL_D3Q19_Gradient_DFH(NeighborList, Phi, Gradient, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_D3Q19_Gradient_DFH(NeighborList, Phi, Gradient,
ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->SendHalo(Phi); ScaLBL_Comm->SendHalo(Phi);
ScaLBL_D3Q19_Gradient_DFH(NeighborList, Phi, Gradient, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_D3Q19_Gradient_DFH(NeighborList, Phi, Gradient, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_Comm->RecvGrad(Phi, Gradient); ScaLBL_Comm->RecvGrad(Phi, Gradient);
// Perform the collision operation // Perform the collision operation
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
ScaLBL_D3Q19_AAodd_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient, SolidPotential, rhoA, rhoB, tauA, tauB, ScaLBL_D3Q19_AAodd_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient,
alpha, beta, Fx, Fy, Fz, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); SolidPotential, rhoA, rhoB, tauA, tauB, alpha,
beta, Fx, Fy, Fz, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
// Set BCs // Set BCs
if (BoundaryCondition > 0) { if (BoundaryCondition > 0) {
@ -530,31 +570,42 @@ void ScaLBL_DFHModel::Run(){
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
} }
if (BoundaryCondition == 4) { if (BoundaryCondition == 4) {
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep); din =
ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
} }
ScaLBL_D3Q19_AAodd_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient, SolidPotential, rhoA, rhoB, tauA, tauB, ScaLBL_D3Q19_AAodd_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient,
alpha, beta, Fx, Fy, Fz, 0, ScaLBL_Comm->LastExterior(), Np); SolidPotential, rhoA, rhoB, tauA, tauB, alpha,
ScaLBL_DeviceBarrier(); comm.barrier(); beta, Fx, Fy, Fz, 0, ScaLBL_Comm->LastExterior(),
Np);
ScaLBL_DeviceBarrier();
comm.barrier();
// *************EVEN TIMESTEP************* // *************EVEN TIMESTEP*************
timestep++; timestep++;
// Compute the Phase indicator field // Compute the Phase indicator field
ScaLBL_Comm->BiSendD3Q7AA(Aq, Bq); //READ FROM NORMAL ScaLBL_Comm->BiSendD3Q7AA(Aq, Bq); //READ FROM NORMAL
ScaLBL_D3Q7_AAeven_DFH(Aq, Bq, Den, Phi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_D3Q7_AAeven_DFH(Aq, Bq, Den, Phi, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->BiRecvD3Q7AA(Aq, Bq); //WRITE INTO OPPOSITE ScaLBL_Comm->BiRecvD3Q7AA(Aq, Bq); //WRITE INTO OPPOSITE
ScaLBL_D3Q7_AAeven_DFH(Aq, Bq, Den, Phi, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_D3Q7_AAeven_DFH(Aq, Bq, Den, Phi, 0, ScaLBL_Comm->LastExterior(),
Np);
// compute the gradient // compute the gradient
ScaLBL_D3Q19_Gradient_DFH(NeighborList, Phi, Gradient, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_D3Q19_Gradient_DFH(NeighborList, Phi, Gradient,
ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->SendHalo(Phi); ScaLBL_Comm->SendHalo(Phi);
ScaLBL_D3Q19_Gradient_DFH(NeighborList, Phi, Gradient, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_D3Q19_Gradient_DFH(NeighborList, Phi, Gradient, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_Comm->RecvGrad(Phi, Gradient); ScaLBL_Comm->RecvGrad(Phi, Gradient);
// Perform the collision operation // Perform the collision operation
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
ScaLBL_D3Q19_AAeven_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient, SolidPotential, rhoA, rhoB, tauA, tauB, ScaLBL_D3Q19_AAeven_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient,
alpha, beta, Fx, Fy, Fz, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); SolidPotential, rhoA, rhoB, tauA, tauB, alpha,
beta, Fx, Fy, Fz, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
// Set boundary conditions // Set boundary conditions
if (BoundaryCondition > 0) { if (BoundaryCondition > 0) {
@ -564,20 +615,24 @@ void ScaLBL_DFHModel::Run(){
if (BoundaryCondition == 3) { if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
} } else if (BoundaryCondition == 4) {
else if (BoundaryCondition == 4){ din =
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep); ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
} }
ScaLBL_D3Q19_AAeven_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient, SolidPotential, rhoA, rhoB, tauA, tauB, ScaLBL_D3Q19_AAeven_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient,
alpha, beta, Fx, Fy, Fz, 0, ScaLBL_Comm->LastExterior(), Np); SolidPotential, rhoA, rhoB, tauA, tauB, alpha,
ScaLBL_DeviceBarrier(); comm.barrier(); beta, Fx, Fy, Fz, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_DeviceBarrier();
comm.barrier();
//************************************************************************ //************************************************************************
comm.barrier(); comm.barrier();
PROFILE_STOP("Update"); PROFILE_STOP("Update");
// Run the analysis // Run the analysis
analysis.run(timestep, analysis_db, *Averages, Phi, Pressure, Velocity, fq, Den ); analysis.run(timestep, analysis_db, *Averages, Phi, Pressure, Velocity,
fq, Den);
} }
analysis.finish(); analysis.finish();
PROFILE_STOP("Loop"); PROFILE_STOP("Loop");
@ -585,18 +640,25 @@ void ScaLBL_DFHModel::Run(){
//************************************************************************ //************************************************************************
ScaLBL_DeviceBarrier(); ScaLBL_DeviceBarrier();
comm.barrier(); comm.barrier();
if (rank==0) printf("-------------------------------------------------------------------\n"); if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep // Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now(); auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep; double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep;
// Performance obtained from each node // Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000; double MLUPS = double(Np) / cputime / 1000000;
if (rank==0) printf("********************************************************\n"); if (rank == 0)
if (rank==0) printf("CPU time = %f \n", cputime); printf("********************************************************\n");
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS); if (rank == 0)
printf("CPU time = %f \n", cputime);
if (rank == 0)
printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
MLUPS *= nprocs; MLUPS *= nprocs;
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS); if (rank == 0)
if (rank==0) printf("********************************************************\n"); printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
// ************************************************************************ // ************************************************************************
} }
@ -624,5 +686,4 @@ void ScaLBL_DFHModel::WriteDebug(){
BFILE = fopen(LocalRankFilename, "wb"); BFILE = fopen(LocalRankFilename, "wb");
fwrite(PhaseField.data(), 8, N, BFILE); fwrite(PhaseField.data(), 8, N, BFILE);
fclose(BFILE); fclose(BFILE);
} }

View File

@ -78,6 +78,4 @@ private:
//int rank,nprocs; //int rank,nprocs;
void LoadParams(std::shared_ptr<Database> db0); void LoadParams(std::shared_ptr<Database> db0);
void AssignComponentLabels(double *phase); void AssignComponentLabels(double *phase);
}; };

View File

@ -9,18 +9,15 @@ color lattice boltzmann model
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
ScaLBL_FreeLeeModel::ScaLBL_FreeLeeModel(int RANK, int NP, const Utilities::MPI& COMM): ScaLBL_FreeLeeModel::ScaLBL_FreeLeeModel(int RANK, int NP,
rank(RANK), nprocs(NP), Restart(0),timestep(0),timestepMax(2),tauA(1.0),tauB(1.0),tauM(1.0),rhoA(1.0),rhoB(1.0),W(5.0),gamma(0.001),kappa(0.0075),beta(0.0024), const Utilities::MPI &COMM)
Fx(0),Fy(0),Fz(0),flux(0),din(0),dout(0),inletA(0),inletB(0),outletA(0),outletB(0), : rank(RANK), nprocs(NP), Restart(0), timestep(0), timestepMax(2),
tau(1.0),rho0(1.0), tauA(1.0), tauB(1.0), tauM(1.0), rhoA(1.0), rhoB(1.0), W(5.0),
Nx(0),Ny(0),Nz(0),N(0),Np(0),nprocx(0),nprocy(0),nprocz(0),BoundaryCondition(0),Lx(0),Ly(0),Lz(0),comm(COMM) gamma(0.001), kappa(0.0075), beta(0.0024), Fx(0), Fy(0), Fz(0), flux(0),
{ din(0), dout(0), inletA(0), inletB(0), outletA(0), outletB(0), tau(1.0),
rho0(1.0), Nx(0), Ny(0), Nz(0), N(0), Np(0), nprocx(0), nprocy(0),
} nprocz(0), BoundaryCondition(0), Lx(0), Ly(0), Lz(0), comm(COMM) {}
ScaLBL_FreeLeeModel::~ScaLBL_FreeLeeModel(){ ScaLBL_FreeLeeModel::~ScaLBL_FreeLeeModel() {}
}
void ScaLBL_FreeLeeModel::getPhase(DoubleArray &PhaseValues) { void ScaLBL_FreeLeeModel::getPhase(DoubleArray &PhaseValues) {
@ -37,29 +34,36 @@ void ScaLBL_FreeLeeModel::getPhase(DoubleArray &PhaseValues){
} }
} }
void ScaLBL_FreeLeeModel::getPotential(DoubleArray &PressureValues, DoubleArray &MuValues){ void ScaLBL_FreeLeeModel::getPotential(DoubleArray &PressureValues,
DoubleArray &MuValues) {
ScaLBL_Comm->RegularLayout(Map, Pressure, PressureValues); ScaLBL_Comm->RegularLayout(Map, Pressure, PressureValues);
ScaLBL_Comm->Barrier(); comm.barrier(); ScaLBL_Comm->Barrier();
comm.barrier();
ScaLBL_Comm->RegularLayout(Map, mu_phi, MuValues); ScaLBL_Comm->RegularLayout(Map, mu_phi, MuValues);
ScaLBL_Comm->Barrier(); comm.barrier(); ScaLBL_Comm->Barrier();
comm.barrier();
} }
void ScaLBL_FreeLeeModel::getVelocity(DoubleArray &Vel_x, DoubleArray &Vel_y, DoubleArray &Vel_z){ void ScaLBL_FreeLeeModel::getVelocity(DoubleArray &Vel_x, DoubleArray &Vel_y,
DoubleArray &Vel_z) {
ScaLBL_Comm->RegularLayout(Map, &Velocity[0], Vel_x); ScaLBL_Comm->RegularLayout(Map, &Velocity[0], Vel_x);
ScaLBL_Comm->Barrier(); comm.barrier(); ScaLBL_Comm->Barrier();
comm.barrier();
ScaLBL_Comm->RegularLayout(Map, &Velocity[Np], Vel_y); ScaLBL_Comm->RegularLayout(Map, &Velocity[Np], Vel_y);
ScaLBL_Comm->Barrier(); comm.barrier(); ScaLBL_Comm->Barrier();
comm.barrier();
ScaLBL_Comm->RegularLayout(Map, &Velocity[2 * Np], Vel_z); ScaLBL_Comm->RegularLayout(Map, &Velocity[2 * Np], Vel_z);
ScaLBL_Comm->Barrier(); comm.barrier(); ScaLBL_Comm->Barrier();
comm.barrier();
} }
void ScaLBL_FreeLeeModel::getData_RegularLayout(const double *data, DoubleArray &regdata){ void ScaLBL_FreeLeeModel::getData_RegularLayout(const double *data,
DoubleArray &regdata) {
// Gets data (in optimized layout) from the HOST and stores in regular layout // Gets data (in optimized layout) from the HOST and stores in regular layout
// Primarly for debugging // Primarly for debugging
int i, j, k, idx; int i, j, k, idx;
@ -102,7 +106,8 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
//beta = 12.0*gamma/W; //beta = 12.0*gamma/W;
//kappa = 3.0*gamma*W/2.0;//beta and kappa are related to surface tension \gamma //kappa = 3.0*gamma*W/2.0;//beta and kappa are related to surface tension \gamma
beta = 0.75 * gamma / W; beta = 0.75 * gamma / W;
kappa = 0.375*gamma*W;//beta and kappa are related to surface tension \gamma kappa = 0.375 * gamma *
W; //beta and kappa are related to surface tension \gamma
Restart = false; Restart = false;
din = dout = 1.0; din = dout = 1.0;
flux = 0.0; flux = 0.0;
@ -163,7 +168,8 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
//beta = 12.0*gamma/W; //beta = 12.0*gamma/W;
//kappa = 3.0*gamma*W/2.0;//beta and kappa are related to surface tension \gamma //kappa = 3.0*gamma*W/2.0;//beta and kappa are related to surface tension \gamma
beta = 0.75 * gamma / W; beta = 0.75 * gamma / W;
kappa = 0.375*gamma*W;//beta and kappa are related to surface tension \gamma kappa = 0.375 * gamma *
W; //beta and kappa are related to surface tension \gamma
//if (BoundaryCondition==4) flux *= rhoA; // mass flux must adjust for density (see formulation for details) //if (BoundaryCondition==4) flux *= rhoA; // mass flux must adjust for density (see formulation for details)
BoundaryCondition = 0; BoundaryCondition = 0;
@ -173,8 +179,10 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
} }
void ScaLBL_FreeLeeModel::SetDomain() { void ScaLBL_FreeLeeModel::SetDomain() {
Dm = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // full domain for analysis Dm = std::shared_ptr<Domain>(
Mask = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // mask domain removes immobile phases new Domain(domain_db, comm)); // full domain for analysis
Mask = std::shared_ptr<Domain>(
new Domain(domain_db, comm)); // mask domain removes immobile phases
// domain parameters // domain parameters
Nx = Dm->Nx; Nx = Dm->Nx;
Ny = Dm->Ny; Ny = Dm->Ny;
@ -188,7 +196,8 @@ void ScaLBL_FreeLeeModel::SetDomain(){
Nzh = Nz + 2; Nzh = Nz + 2;
Nh = Nxh * Nyh * Nzh; Nh = Nxh * Nyh * Nzh;
id = new signed char[N]; id = new signed char[N];
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = 1; // initialize this way for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = 1; // initialize this way
comm.barrier(); comm.barrier();
Dm->CommInit(); Dm->CommInit();
@ -212,28 +221,30 @@ void ScaLBL_FreeLeeModel::ReadInput(){
std::string first_image = ImageList[IMAGE_INDEX]; std::string first_image = ImageList[IMAGE_INDEX];
Mask->Decomp(first_image); Mask->Decomp(first_image);
IMAGE_INDEX++; IMAGE_INDEX++;
} } else if (domain_db->keyExists("GridFile")) {
else if (domain_db->keyExists( "GridFile" )){
// Read the local domain data // Read the local domain data
auto input_id = readMicroCT(*domain_db, MPI_COMM_WORLD); auto input_id = readMicroCT(*domain_db, MPI_COMM_WORLD);
// Fill the halo (assuming GCW of 1) // Fill the halo (assuming GCW of 1)
array<int,3> size0 = { (int) input_id.size(0), (int) input_id.size(1), (int) input_id.size(2) }; array<int, 3> size0 = {(int)input_id.size(0), (int)input_id.size(1),
ArraySize size1 = { (size_t) Mask->Nx, (size_t) Mask->Ny, (size_t) Mask->Nz }; (int)input_id.size(2)};
ASSERT( (int) size1[0] == size0[0]+2 && (int) size1[1] == size0[1]+2 && (int) size1[2] == size0[2]+2 ); ArraySize size1 = {(size_t)Mask->Nx, (size_t)Mask->Ny,
fillHalo<signed char> fill( MPI_COMM_WORLD, Mask->rank_info, size0, { 1, 1, 1 }, 0, 1 ); (size_t)Mask->Nz};
ASSERT((int)size1[0] == size0[0] + 2 && (int)size1[1] == size0[1] + 2 &&
(int)size1[2] == size0[2] + 2);
fillHalo<signed char> fill(MPI_COMM_WORLD, Mask->rank_info, size0,
{1, 1, 1}, 0, 1);
Array<signed char> id_view; Array<signed char> id_view;
id_view.viewRaw(size1, Mask->id.data()); id_view.viewRaw(size1, Mask->id.data());
fill.copy(input_id, id_view); fill.copy(input_id, id_view);
fill.fill(id_view); fill.fill(id_view);
} } else if (domain_db->keyExists("Filename")) {
else if (domain_db->keyExists( "Filename" )){
auto Filename = domain_db->getScalar<std::string>("Filename"); auto Filename = domain_db->getScalar<std::string>("Filename");
Mask->Decomp(Filename); Mask->Decomp(Filename);
} } else {
else{
Mask->ReadIDs(); Mask->ReadIDs();
} }
for (int i=0; i<Nx*Ny*Nz; i++) id[i] = Mask->id[i]; // save what was read for (int i = 0; i < Nx * Ny * Nz; i++)
id[i] = Mask->id[i]; // save what was read
// Generate the signed distance map // Generate the signed distance map
// Initialize the domain and communication // Initialize the domain and communication
@ -245,8 +256,10 @@ void ScaLBL_FreeLeeModel::ReadInput(){
int n = k * Nx * Ny + j * Nx + i; int n = k * Nx * Ny + j * Nx + i;
// Initialize the solid phase // Initialize the solid phase
signed char label = Mask->id[n]; signed char label = Mask->id[n];
if (label > 0) id_solid(i,j,k) = 1; if (label > 0)
else id_solid(i,j,k) = 0; id_solid(i, j, k) = 1;
else
id_solid(i, j, k) = 0;
} }
} }
} }
@ -260,11 +273,13 @@ void ScaLBL_FreeLeeModel::ReadInput(){
} }
} }
} }
if (rank==0) printf("Initialized solid phase -- Converting to Signed Distance function \n"); if (rank == 0)
printf("Initialized solid phase -- Converting to Signed Distance "
"function \n");
CalcDist(SignDist, id_solid, *Mask); CalcDist(SignDist, id_solid, *Mask);
if (rank == 0) cout << "Domain set." << endl; if (rank == 0)
cout << "Domain set." << endl;
} }
void ScaLBL_FreeLeeModel::Create_TwoFluid() { void ScaLBL_FreeLeeModel::Create_TwoFluid() {
@ -273,30 +288,38 @@ void ScaLBL_FreeLeeModel::Create_TwoFluid(){
*/ */
//......................................................... //.........................................................
// Initialize communication structures in averaging domain // Initialize communication structures in averaging domain
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
Mask->CommInit(); Mask->CommInit();
Np = Mask->PoreCount(); Np = Mask->PoreCount();
//........................................................................... //...........................................................................
if (rank==0) printf ("Create ScaLBL_Communicator \n"); if (rank == 0)
printf("Create ScaLBL_Communicator \n");
// Create a communicator for the device (will use optimized layout) // Create a communicator for the device (will use optimized layout)
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original // ScaLBL_Communicator ScaLBL_Comm(Mask); // original
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask)); ScaLBL_Comm =
std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
//ScaLBL_Comm_Regular = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask)); //ScaLBL_Comm_Regular = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
ScaLBL_Comm_WideHalo = std::shared_ptr<ScaLBLWideHalo_Communicator>(new ScaLBLWideHalo_Communicator(Mask,2)); ScaLBL_Comm_WideHalo = std::shared_ptr<ScaLBLWideHalo_Communicator>(
new ScaLBLWideHalo_Communicator(Mask, 2));
// create the layout for the LBM // create the layout for the LBM
int Npad = (Np / 16 + 2) * 16; int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N); if (rank == 0)
Map.resize(Nx,Ny,Nz); Map.fill(-2); printf("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx, Ny, Nz);
Map.fill(-2);
auto neighborList = new int[18 * Npad]; auto neighborList = new int[18 * Npad];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,2); Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 2);
comm.barrier(); comm.barrier();
//........................................................................... //...........................................................................
// MAIN VARIABLES ALLOCATED HERE // MAIN VARIABLES ALLOCATED HERE
//........................................................................... //...........................................................................
// LBM variables // LBM variables
if (rank==0) printf ("Allocating distributions \n"); if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions................................. //......................device distributions.................................
dist_mem_size = Np * sizeof(double); dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int)); neighborSize = 18 * (Np * sizeof(int));
@ -313,7 +336,8 @@ void ScaLBL_FreeLeeModel::Create_TwoFluid(){
ScaLBL_AllocateDeviceMemory((void **)&ColorGrad, 3 * sizeof(double) * Np); ScaLBL_AllocateDeviceMemory((void **)&ColorGrad, 3 * sizeof(double) * Np);
//........................................................................... //...........................................................................
// Update GPU data structures // Update GPU data structures
if (rank==0) printf ("Setting up device map and neighbor list \n"); if (rank == 0)
printf("Setting up device map and neighbor list \n");
fflush(stdout); fflush(stdout);
int *TmpMap; int *TmpMap;
TmpMap = new int[Np]; TmpMap = new int[Np];
@ -334,7 +358,8 @@ void ScaLBL_FreeLeeModel::Create_TwoFluid(){
TmpMap[idx] = Nxh * Nyh * Nzh - 1; TmpMap[idx] = Nxh * Nyh * Nzh - 1;
} }
} }
for (int idx=ScaLBL_Comm->FirstInterior(); idx<ScaLBL_Comm->LastInterior(); idx++){ for (int idx = ScaLBL_Comm->FirstInterior();
idx < ScaLBL_Comm->LastInterior(); idx++) {
auto n = TmpMap[idx]; auto n = TmpMap[idx];
if (n > Nxh * Nyh * Nzh) { if (n > Nxh * Nyh * Nzh) {
printf("Bad value! idx=%i \n", n); printf("Bad value! idx=%i \n", n);
@ -356,28 +381,35 @@ void ScaLBL_FreeLeeModel::Create_SingleFluid(){
*/ */
//......................................................... //.........................................................
// Initialize communication structures in averaging domain // Initialize communication structures in averaging domain
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
Mask->CommInit(); Mask->CommInit();
Np = Mask->PoreCount(); Np = Mask->PoreCount();
//........................................................................... //...........................................................................
if (rank==0) printf ("Create ScaLBL_Communicator \n"); if (rank == 0)
printf("Create ScaLBL_Communicator \n");
// Create a communicator for the device (will use optimized layout) // Create a communicator for the device (will use optimized layout)
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original // ScaLBL_Communicator ScaLBL_Comm(Mask); // original
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask)); ScaLBL_Comm =
std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
// create the layout for the LBM // create the layout for the LBM
int Npad = (Np / 16 + 2) * 16; int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N); if (rank == 0)
Map.resize(Nx,Ny,Nz); Map.fill(-2); printf("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx, Ny, Nz);
Map.fill(-2);
auto neighborList = new int[18 * Npad]; auto neighborList = new int[18 * Npad];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1); Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 1);
comm.barrier(); comm.barrier();
//........................................................................... //...........................................................................
// MAIN VARIABLES ALLOCATED HERE // MAIN VARIABLES ALLOCATED HERE
//........................................................................... //...........................................................................
// LBM variables // LBM variables
if (rank==0) printf ("Allocating distributions \n"); if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions................................. //......................device distributions.................................
dist_mem_size = Np * sizeof(double); dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int)); neighborSize = 18 * (Np * sizeof(int));
@ -388,15 +420,15 @@ void ScaLBL_FreeLeeModel::Create_SingleFluid(){
ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np); ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np);
//........................................................................... //...........................................................................
// Update GPU data structures // Update GPU data structures
if (rank==0) printf ("Setting up device map and neighbor list \n"); if (rank == 0)
printf("Setting up device map and neighbor list \n");
// copy the neighbor list // copy the neighbor list
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize); ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
comm.barrier(); comm.barrier();
delete[] neighborList; delete[] neighborList;
} }
void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad() void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad() {
{
double *phase; double *phase;
phase = new double[Nh]; phase = new double[Nh];
@ -409,7 +441,8 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
NLABELS = LabelList.size(); NLABELS = LabelList.size();
if (NLABELS != AffinityList.size()) { if (NLABELS != AffinityList.size()) {
ERROR("Error: ComponentLabels and ComponentAffinity must be the same length! \n"); ERROR("Error: ComponentLabels and ComponentAffinity must be the same "
"length! \n");
} }
double *label_count; double *label_count;
@ -418,7 +451,8 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
label_count_global = new double[NLABELS]; label_count_global = new double[NLABELS];
// Assign the labels // Assign the labels
for (size_t idx=0; idx<NLABELS; idx++) label_count[idx]=0; for (size_t idx = 0; idx < NLABELS; idx++)
label_count[idx] = 0;
for (int k = 0; k < Nzh; k++) { for (int k = 0; k < Nzh; k++) {
for (int j = 0; j < Nyh; j++) { for (int j = 0; j < Nyh; j++) {
for (int i = 0; i < Nxh; i++) { for (int i = 0; i < Nxh; i++) {
@ -430,12 +464,18 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
int x = i - 1; int x = i - 1;
int y = j - 1; int y = j - 1;
int z = k - 1; int z = k - 1;
if (x<0) x=0; if (x < 0)
if (y<0) y=0; x = 0;
if (z<0) z=0; if (y < 0)
if (x>=Nx) x=Nx-1; y = 0;
if (y>=Ny) y=Ny-1; if (z < 0)
if (z>=Nz) z=Nz-1; z = 0;
if (x >= Nx)
x = Nx - 1;
if (y >= Ny)
y = Ny - 1;
if (z >= Nz)
z = Nz - 1;
int n = z * Nx * Ny + y * Nx + x; int n = z * Nx * Ny + y * Nx + x;
VALUE = id[n]; VALUE = id[n];
@ -450,15 +490,18 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
} }
} }
// fluid labels are reserved // fluid labels are reserved
if (VALUE == 1) AFFINITY=1.0; if (VALUE == 1)
else if (VALUE == 2) AFFINITY=-1.0; AFFINITY = 1.0;
else if (VALUE == 2)
AFFINITY = -1.0;
phase[nh] = AFFINITY; phase[nh] = AFFINITY;
} }
} }
} }
// Set Dm to match Mask // Set Dm to match Mask
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
for (size_t idx = 0; idx < NLABELS; idx++) for (size_t idx = 0; idx < NLABELS; idx++)
label_count_global[idx] = Dm->Comm.sumReduce(label_count[idx]); label_count_global[idx] = Dm->Comm.sumReduce(label_count[idx]);
@ -468,8 +511,11 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
for (unsigned int idx = 0; idx < NLABELS; idx++) { for (unsigned int idx = 0; idx < NLABELS; idx++) {
VALUE = LabelList[idx]; VALUE = LabelList[idx];
AFFINITY = AffinityList[idx]; AFFINITY = AffinityList[idx];
double volume_fraction = double(label_count_global[idx])/double((Nx-2)*(Ny-2)*(Nz-2)*nprocs); double volume_fraction =
printf(" label=%d, affinity=%f, volume fraction==%f\n",VALUE,AFFINITY,volume_fraction); double(label_count_global[idx]) /
double((Nx - 2) * (Ny - 2) * (Nz - 2) * nprocs);
printf(" label=%d, affinity=%f, volume fraction==%f\n", VALUE,
AFFINITY, volume_fraction);
} }
} }
@ -484,7 +530,9 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
for (int jj = 0; jj < 3; jj++) { for (int jj = 0; jj < 3; jj++) {
for (int ii = 0; ii < 3; ii++) { for (int ii = 0; ii < 3; ii++) {
int index = kk * 9 + jj * 3 + ii; int index = kk * 9 + jj * 3 + ii;
Dst[index] = sqrt(double(ii-1)*double(ii-1) + double(jj-1)*double(jj-1)+ double(kk-1)*double(kk-1)); Dst[index] = sqrt(double(ii - 1) * double(ii - 1) +
double(jj - 1) * double(jj - 1) +
double(kk - 1) * double(kk - 1));
} }
} }
} }
@ -524,7 +572,8 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
Dst[25] = w_edge; Dst[25] = w_edge;
double cs2_inv = 3.0; //inverse of c_s^2 for D3Q19 lattice double cs2_inv = 3.0; //inverse of c_s^2 for D3Q19 lattice
int width = 2;//For better readability: make halo width explicity wherever possible int width =
2; //For better readability: make halo width explicity wherever possible
for (int k = width; k < Nzh - width; k++) { for (int k = width; k < Nzh - width; k++) {
for (int j = width; j < Nyh - width; j++) { for (int j = width; j < Nyh - width; j++) {
for (int i = width; i < Nxh - width; i++) { for (int i = width; i < Nxh - width; i++) {
@ -549,12 +598,18 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
int idj = j + jj - 1; int idj = j + jj - 1;
int idk = k + kk - 1; int idk = k + kk - 1;
if (idi < 0) idi=0; if (idi < 0)
if (idj < 0) idj=0; idi = 0;
if (idk < 0) idk=0; if (idj < 0)
if (!(idi < Nxh)) idi=Nxh-1; idj = 0;
if (!(idj < Nyh)) idj=Nyh-1; if (idk < 0)
if (!(idk < Nzh)) idk=Nzh-1; idk = 0;
if (!(idi < Nxh))
idi = Nxh - 1;
if (!(idj < Nyh))
idj = Nyh - 1;
if (!(idk < Nzh))
idk = Nzh - 1;
int nn = idk * Nxh * Nyh + idj * Nxh + idi; int nn = idk * Nxh * Nyh + idj * Nxh + idi;
double vec_x = double(ii - 1); double vec_x = double(ii - 1);
@ -565,7 +620,10 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
phi_x += GWNS * weight * vec_x; phi_x += GWNS * weight * vec_x;
phi_y += GWNS * weight * vec_y; phi_y += GWNS * weight * vec_y;
phi_z += GWNS * weight * vec_z; phi_z += GWNS * weight * vec_z;
phi_Lap += weight*(GWNS-GWNS_local);//Laplacian of the phase field phi_Lap +=
weight *
(GWNS -
GWNS_local); //Laplacian of the phase field
} }
} }
} }
@ -575,7 +633,10 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
ColorGrad_host[idx + 2 * Np] = cs2_inv * phi_z; ColorGrad_host[idx + 2 * Np] = cs2_inv * phi_z;
//compute chemical potential //compute chemical potential
phi_Lap = 2.0 * cs2_inv * phi_Lap; phi_Lap = 2.0 * cs2_inv * phi_Lap;
mu_phi_host[idx] = 4.0*beta*phase[nh]*(phase[nh]+1.0)*(phase[nh]-1.0) - kappa*phi_Lap; mu_phi_host[idx] = 4.0 * beta * phase[nh] *
(phase[nh] + 1.0) *
(phase[nh] - 1.0) -
kappa * phi_Lap;
} }
} }
} }
@ -636,15 +697,25 @@ void ScaLBL_FreeLeeModel::Initialize_TwoFluid(){
/* /*
* This function initializes two-fluid Lee model * This function initializes two-fluid Lee model
*/ */
if (rank==0) printf ("Initializing phase field, chemical potential and color gradient\n"); if (rank == 0)
printf("Initializing phase field, chemical potential and color "
"gradient\n");
AssignComponentLabels_ChemPotential_ColorGrad(); //initialize phase field Phi AssignComponentLabels_ChemPotential_ColorGrad(); //initialize phase field Phi
if (rank==0) printf ("Initializing distributions for momentum transport\n"); if (rank == 0)
ScaLBL_D3Q19_FreeLeeModel_TwoFluid_Init(gqbar, mu_phi, ColorGrad, Fx, Fy, Fz, Np); printf("Initializing distributions for momentum transport\n");
ScaLBL_D3Q19_FreeLeeModel_TwoFluid_Init(gqbar, mu_phi, ColorGrad, Fx, Fy,
Fz, Np);
if (rank==0) printf ("Initializing density field and distributions for phase-field transport\n"); if (rank == 0)
ScaLBL_FreeLeeModel_PhaseField_Init(dvcMap, Phi, Den, hq, ColorGrad, rhoA, rhoB, tauM, W, 0, ScaLBL_Comm->LastExterior(), Np); printf("Initializing density field and distributions for phase-field "
ScaLBL_FreeLeeModel_PhaseField_Init(dvcMap, Phi, Den, hq, ColorGrad, rhoA, rhoB, tauM, W, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); "transport\n");
ScaLBL_FreeLeeModel_PhaseField_Init(dvcMap, Phi, Den, hq, ColorGrad, rhoA,
rhoB, tauM, W, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_FreeLeeModel_PhaseField_Init(
dvcMap, Phi, Den, hq, ColorGrad, rhoA, rhoB, tauM, W,
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
if (Restart == true) { if (Restart == true) {
//TODO need to revise this function //TODO need to revise this function
@ -689,7 +760,8 @@ void ScaLBL_FreeLeeModel::Initialize_TwoFluid(){
if (!(idx < 0) && idx < N) if (!(idx < 0) && idx < N)
cPhi[idx] = value; cPhi[idx] = value;
} }
for (int n=ScaLBL_Comm->FirstInterior(); n<ScaLBL_Comm->LastInterior(); n++){ for (int n = ScaLBL_Comm->FirstInterior();
n < ScaLBL_Comm->LastInterior(); n++) {
va = cDen[n]; va = cDen[n];
vb = cDen[Np + n]; vb = cDen[Np + n];
value = (va - vb) / (va + vb); value = (va - vb) / (va + vb);
@ -705,7 +777,9 @@ void ScaLBL_FreeLeeModel::Initialize_TwoFluid(){
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
comm.barrier(); comm.barrier();
if (rank==0) printf ("Initializing phase and density fields on device from Restart\n"); if (rank == 0)
printf("Initializing phase and density fields on device from "
"Restart\n");
//TODO the following function is to be updated. //TODO the following function is to be updated.
//ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, 0, ScaLBL_Comm->LastExterior(), Np); //ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, 0, ScaLBL_Comm->LastExterior(), Np);
//ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); //ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
@ -713,7 +787,8 @@ void ScaLBL_FreeLeeModel::Initialize_TwoFluid(){
// establish reservoirs for external bC // establish reservoirs for external bC
// TODO to be revised // TODO to be revised
if (BoundaryCondition == 1 || BoundaryCondition == 2 || BoundaryCondition == 3 || BoundaryCondition == 4 ){ if (BoundaryCondition == 1 || BoundaryCondition == 2 ||
BoundaryCondition == 3 || BoundaryCondition == 4) {
if (Dm->kproc() == 0) { if (Dm->kproc() == 0) {
ScaLBL_SetSlice_z(Phi, 1.0, Nx, Ny, Nz, 0); ScaLBL_SetSlice_z(Phi, 1.0, Nx, Ny, Nz, 0);
ScaLBL_SetSlice_z(Phi, 1.0, Nx, Ny, Nz, 1); ScaLBL_SetSlice_z(Phi, 1.0, Nx, Ny, Nz, 1);
@ -732,7 +807,8 @@ void ScaLBL_FreeLeeModel::Initialize_SingleFluid(){
/* /*
* This function initializes single-fluid Lee model * This function initializes single-fluid Lee model
*/ */
if (rank==0) printf ("Initializing distributions for momentum transport\n"); if (rank == 0)
printf("Initializing distributions for momentum transport\n");
ScaLBL_D3Q19_FreeLeeModel_SingleFluid_Init(gqbar, Fx, Fy, Fz, Np); ScaLBL_D3Q19_FreeLeeModel_SingleFluid_Init(gqbar, Fx, Fy, Fz, Np);
if (Restart == true) { if (Restart == true) {
@ -759,11 +835,15 @@ double ScaLBL_FreeLeeModel::Run_TwoFluid(int returntime){
// Compute the Phase indicator field // Compute the Phase indicator field
// Read for hq happens in this routine (requires communication) // Read for hq happens in this routine (requires communication)
ScaLBL_Comm->SendD3Q7AA(hq, 0); //READ FROM NORMAL ScaLBL_Comm->SendD3Q7AA(hq, 0); //READ FROM NORMAL
ScaLBL_D3Q7_AAodd_FreeLeeModel_PhaseField(NeighborList, dvcMap, hq, Den, Phi, rhoA, rhoB, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_D3Q7_AAodd_FreeLeeModel_PhaseField(
NeighborList, dvcMap, hq, Den, Phi, rhoA, rhoB,
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
//ScaLBL_D3Q7_AAodd_FreeLee_PhaseField(NeighborList, dvcMap, hq, Den, Phi, ColorGrad, Velocity, rhoA, rhoB, tauM, W, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); //ScaLBL_D3Q7_AAodd_FreeLee_PhaseField(NeighborList, dvcMap, hq, Den, Phi, ColorGrad, Velocity, rhoA, rhoB, tauM, W, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->RecvD3Q7AA(hq, 0); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q7AA(hq, 0); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
ScaLBL_D3Q7_AAodd_FreeLeeModel_PhaseField(NeighborList, dvcMap, hq, Den, Phi, rhoA, rhoB, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_D3Q7_AAodd_FreeLeeModel_PhaseField(
NeighborList, dvcMap, hq, Den, Phi, rhoA, rhoB, 0,
ScaLBL_Comm->LastExterior(), Np);
//ScaLBL_D3Q7_AAodd_FreeLee_PhaseField(NeighborList, dvcMap, hq, Den, Phi, ColorGrad, Velocity, rhoA, rhoB, tauM, W, 0, ScaLBL_Comm->LastExterior(), Np); //ScaLBL_D3Q7_AAodd_FreeLee_PhaseField(NeighborList, dvcMap, hq, Den, Phi, ColorGrad, Velocity, rhoA, rhoB, tauM, W, 0, ScaLBL_Comm->LastExterior(), Np);
// Perform the collision operation // Perform the collision operation
@ -781,41 +861,52 @@ double ScaLBL_FreeLeeModel::Run_TwoFluid(int returntime){
ScaLBL_Comm_WideHalo->Send(Phi); ScaLBL_Comm_WideHalo->Send(Phi);
//ScaLBL_D3Q19_AAodd_FreeLeeModel(NeighborList, dvcMap, gqbar, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, //ScaLBL_D3Q19_AAodd_FreeLeeModel(NeighborList, dvcMap, gqbar, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB,
// kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); // kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
ScaLBL_D3Q19_AAodd_FreeLeeModel_Combined(NeighborList, dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM, ScaLBL_D3Q19_AAodd_FreeLeeModel_Combined(
kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); NeighborList, dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity,
Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM, kappa, beta, W,
Fx, Fy, Fz, Nxh, Nxh * Nyh, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm_WideHalo->Recv(Phi); ScaLBL_Comm_WideHalo->Recv(Phi);
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
// Set BCs // Set BCs
if (BoundaryCondition == 3) { if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din,
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep); timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
timestep);
} }
if (BoundaryCondition == 4) { if (BoundaryCondition == 4) {
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep); din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux,
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep); timestep);
} ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
else if (BoundaryCondition == 5){ timestep);
} else if (BoundaryCondition == 5) {
ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar); ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar);
ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar); ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar);
} }
//ScaLBL_D3Q19_AAodd_FreeLeeModel(NeighborList, dvcMap, gqbar, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, //ScaLBL_D3Q19_AAodd_FreeLeeModel(NeighborList, dvcMap, gqbar, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB,
// kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, 0, ScaLBL_Comm->LastExterior(), Np); // kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, 0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_D3Q19_AAodd_FreeLeeModel_Combined(NeighborList, dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM, ScaLBL_D3Q19_AAodd_FreeLeeModel_Combined(
kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, 0, ScaLBL_Comm->LastExterior(), Np); NeighborList, dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity,
Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM, kappa, beta, W,
Fx, Fy, Fz, Nxh, Nxh * Nyh, 0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
// *************EVEN TIMESTEP************* // *************EVEN TIMESTEP*************
timestep++; timestep++;
// Compute the Phase indicator field // Compute the Phase indicator field
ScaLBL_Comm->SendD3Q7AA(hq, 0); //READ FROM NORMA ScaLBL_Comm->SendD3Q7AA(hq, 0); //READ FROM NORMA
ScaLBL_D3Q7_AAeven_FreeLeeModel_PhaseField(dvcMap, hq, Den, Phi, rhoA, rhoB, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_D3Q7_AAeven_FreeLeeModel_PhaseField(
dvcMap, hq, Den, Phi, rhoA, rhoB, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
//ScaLBL_D3Q7_AAeven_FreeLee_PhaseField(dvcMap, hq, Den, Phi, ColorGrad, Velocity, rhoA, rhoB, tauM, W, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); //ScaLBL_D3Q7_AAeven_FreeLee_PhaseField(dvcMap, hq, Den, Phi, ColorGrad, Velocity, rhoA, rhoB, tauM, W, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->RecvD3Q7AA(hq, 0); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q7AA(hq, 0); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
ScaLBL_D3Q7_AAeven_FreeLeeModel_PhaseField(dvcMap, hq, Den, Phi, rhoA, rhoB, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_D3Q7_AAeven_FreeLeeModel_PhaseField(
dvcMap, hq, Den, Phi, rhoA, rhoB, 0, ScaLBL_Comm->LastExterior(),
Np);
//ScaLBL_D3Q7_AAeven_FreeLee_PhaseField(dvcMap, hq, Den, Phi, ColorGrad, Velocity, rhoA, rhoB, tauM, W, 0, ScaLBL_Comm->LastExterior(), Np); //ScaLBL_D3Q7_AAeven_FreeLee_PhaseField(dvcMap, hq, Den, Phi, ColorGrad, Velocity, rhoA, rhoB, tauM, W, 0, ScaLBL_Comm->LastExterior(), Np);
// Perform the collision operation // Perform the collision operation
@ -831,28 +922,35 @@ double ScaLBL_FreeLeeModel::Run_TwoFluid(int returntime){
ScaLBL_Comm_WideHalo->Send(Phi); ScaLBL_Comm_WideHalo->Send(Phi);
//ScaLBL_D3Q19_AAeven_FreeLeeModel(dvcMap, gqbar, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, //ScaLBL_D3Q19_AAeven_FreeLeeModel(dvcMap, gqbar, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB,
// kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); // kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
ScaLBL_D3Q19_AAeven_FreeLeeModel_Combined(dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM, ScaLBL_D3Q19_AAeven_FreeLeeModel_Combined(
kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad,
rhoA, rhoB, tauA, tauB, tauM, kappa, beta, W, Fx, Fy, Fz, Nxh,
Nxh * Nyh, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm_WideHalo->Recv(Phi); ScaLBL_Comm_WideHalo->Recv(Phi);
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
// Set boundary conditions // Set boundary conditions
if (BoundaryCondition == 3) { if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din,
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep); timestep);
} ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
else if (BoundaryCondition == 4){ timestep);
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep); } else if (BoundaryCondition == 4) {
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep); din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux,
} timestep);
else if (BoundaryCondition == 5){ ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
timestep);
} else if (BoundaryCondition == 5) {
ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar); ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar);
ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar); ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar);
} }
//ScaLBL_D3Q19_AAeven_FreeLeeModel(dvcMap, gqbar, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, //ScaLBL_D3Q19_AAeven_FreeLeeModel(dvcMap, gqbar, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB,
// kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, 0, ScaLBL_Comm->LastExterior(), Np); // kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, 0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_D3Q19_AAeven_FreeLeeModel_Combined(dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM, ScaLBL_D3Q19_AAeven_FreeLeeModel_Combined(
kappa, beta, W, Fx, Fy, Fz, Nxh, Nxh*Nyh, 0, ScaLBL_Comm->LastExterior(), Np); dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad,
rhoA, rhoB, tauA, tauB, tauM, kappa, beta, W, Fx, Fy, Fz, Nxh,
Nxh * Nyh, 0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
//************************************************************************ //************************************************************************
PROFILE_STOP("Update"); PROFILE_STOP("Update");
@ -860,10 +958,13 @@ double ScaLBL_FreeLeeModel::Run_TwoFluid(int returntime){
PROFILE_STOP("Loop"); PROFILE_STOP("Loop");
PROFILE_SAVE("lbpm_color_simulator", 1); PROFILE_SAVE("lbpm_color_simulator", 1);
//************************************************************************ //************************************************************************
if (rank==0) printf("-------------------------------------------------------------------\n"); if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep // Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now(); auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / (EXIT_TIME-START_TIME); double cputime = std::chrono::duration<double>(t2 - t1).count() /
(EXIT_TIME - START_TIME);
// Performance obtained from each node // Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000; double MLUPS = double(Np) / cputime / 1000000;
@ -896,54 +997,62 @@ void ScaLBL_FreeLeeModel::Run_SingleFluid(){
//------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------
// Perform the collision operation // Perform the collision operation
ScaLBL_Comm->SendD3Q19AA(gqbar); //READ FROM NORMAL ScaLBL_Comm->SendD3Q19AA(gqbar); //READ FROM NORMAL
ScaLBL_D3Q19_AAodd_FreeLeeModel_SingleFluid_BGK(NeighborList, gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz, ScaLBL_D3Q19_AAodd_FreeLeeModel_SingleFluid_BGK(
NeighborList, gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz,
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
// Set boundary conditions // Set boundary conditions
// TODO to be revised! // TODO to be revised!
if (BoundaryCondition == 3) { if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din,
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep); timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
timestep);
} }
if (BoundaryCondition == 4) { if (BoundaryCondition == 4) {
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep); din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux,
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep); timestep);
} ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
else if (BoundaryCondition == 5){ timestep);
} else if (BoundaryCondition == 5) {
ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar); ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar);
ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar); ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar);
} }
ScaLBL_D3Q19_AAodd_FreeLeeModel_SingleFluid_BGK(NeighborList, gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz, ScaLBL_D3Q19_AAodd_FreeLeeModel_SingleFluid_BGK(
0, ScaLBL_Comm->LastExterior(), Np); NeighborList, gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
// *************EVEN TIMESTEP************* // *************EVEN TIMESTEP*************
timestep++; timestep++;
//------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------
// Perform the collision operation // Perform the collision operation
ScaLBL_Comm->SendD3Q19AA(gqbar); //READ FORM NORMAL ScaLBL_Comm->SendD3Q19AA(gqbar); //READ FORM NORMAL
ScaLBL_D3Q19_AAeven_FreeLeeModel_SingleFluid_BGK(gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz, ScaLBL_D3Q19_AAeven_FreeLeeModel_SingleFluid_BGK(
gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz,
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
// Set boundary conditions // Set boundary conditions
// TODO to be revised! // TODO to be revised!
if (BoundaryCondition == 3) { if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din,
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep); timestep);
} ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
else if (BoundaryCondition == 4){ timestep);
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep); } else if (BoundaryCondition == 4) {
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep); din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux,
} timestep);
else if (BoundaryCondition == 5){ ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
timestep);
} else if (BoundaryCondition == 5) {
ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar); ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar);
ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar); ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar);
} }
ScaLBL_D3Q19_AAeven_FreeLeeModel_SingleFluid_BGK(gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz, ScaLBL_D3Q19_AAeven_FreeLeeModel_SingleFluid_BGK(
0, ScaLBL_Comm->LastExterior(), Np); gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_Comm->Barrier(); ScaLBL_Comm->Barrier();
//************************************************************************ //************************************************************************
PROFILE_STOP("Update"); PROFILE_STOP("Update");
@ -951,19 +1060,26 @@ void ScaLBL_FreeLeeModel::Run_SingleFluid(){
PROFILE_STOP("Loop"); PROFILE_STOP("Loop");
PROFILE_SAVE("lbpm_color_simulator", 1); PROFILE_SAVE("lbpm_color_simulator", 1);
//************************************************************************ //************************************************************************
if (rank==0) printf("-------------------------------------------------------------------\n"); if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep // Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now(); auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep; double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep;
// Performance obtained from each node // Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000; double MLUPS = double(Np) / cputime / 1000000;
if (rank==0) printf("********************************************************\n"); if (rank == 0)
if (rank==0) printf("CPU time = %f \n", cputime); printf("********************************************************\n");
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS); if (rank == 0)
printf("CPU time = %f \n", cputime);
if (rank == 0)
printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
MLUPS *= nprocs; MLUPS *= nprocs;
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS); if (rank == 0)
if (rank==0) printf("********************************************************\n"); printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
// ************************************************************************ // ************************************************************************
} }
@ -1015,7 +1131,6 @@ void ScaLBL_FreeLeeModel::WriteDebug_TwoFluid(){
DIST = fopen(LocalRankFilename, "wb"); DIST = fopen(LocalRankFilename, "wb");
fwrite(PhaseField.data(), 8, Nx * Ny * Nz, DIST); fwrite(PhaseField.data(), 8, Nx * Ny * Nz, DIST);
fclose(DIST); fclose(DIST);
} }
ScaLBL_Comm->RegularLayout(Map, Den, PhaseField); ScaLBL_Comm->RegularLayout(Map, Den, PhaseField);
@ -1080,7 +1195,6 @@ void ScaLBL_FreeLeeModel::WriteDebug_TwoFluid(){
CGZ_FILE = fopen(LocalRankFilename, "wb"); CGZ_FILE = fopen(LocalRankFilename, "wb");
fwrite(PhaseField.data(), 8, N, CGZ_FILE); fwrite(PhaseField.data(), 8, N, CGZ_FILE);
fclose(CGZ_FILE); fclose(CGZ_FILE);
} }
void ScaLBL_FreeLeeModel::WriteDebug_SingleFluid() { void ScaLBL_FreeLeeModel::WriteDebug_SingleFluid() {
@ -1119,30 +1233,38 @@ void ScaLBL_FreeLeeModel::WriteDebug_SingleFluid(){
void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest() { void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest() {
// Initialize communication structures in averaging domain // Initialize communication structures in averaging domain
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
Mask->CommInit(); Mask->CommInit();
Np = Mask->PoreCount(); Np = Mask->PoreCount();
//........................................................................... //...........................................................................
if (rank==0) printf ("Create ScaLBL_Communicator \n"); if (rank == 0)
printf("Create ScaLBL_Communicator \n");
// Create a communicator for the device (will use optimized layout) // Create a communicator for the device (will use optimized layout)
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original // ScaLBL_Communicator ScaLBL_Comm(Mask); // original
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask)); ScaLBL_Comm =
std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
//ScaLBL_Comm_Regular = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask)); //ScaLBL_Comm_Regular = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
ScaLBL_Comm_WideHalo = std::shared_ptr<ScaLBLWideHalo_Communicator>(new ScaLBLWideHalo_Communicator(Mask,2)); ScaLBL_Comm_WideHalo = std::shared_ptr<ScaLBLWideHalo_Communicator>(
new ScaLBLWideHalo_Communicator(Mask, 2));
// create the layout for the LBM // create the layout for the LBM
int Npad = (Np / 16 + 2) * 16; int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N); if (rank == 0)
Map.resize(Nx,Ny,Nz); Map.fill(-2); printf("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx, Ny, Nz);
Map.fill(-2);
auto neighborList = new int[18 * Npad]; auto neighborList = new int[18 * Npad];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1); Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 1);
comm.barrier(); comm.barrier();
//........................................................................... //...........................................................................
// MAIN VARIABLES ALLOCATED HERE // MAIN VARIABLES ALLOCATED HERE
//........................................................................... //...........................................................................
// LBM variables // LBM variables
if (rank==0) printf ("Allocating distributions \n"); if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions................................. //......................device distributions.................................
dist_mem_size = Np * sizeof(double); dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int)); neighborSize = 18 * (Np * sizeof(int));
@ -1159,7 +1281,8 @@ void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest(){
ScaLBL_AllocateDeviceMemory((void **)&ColorGrad, 3 * sizeof(double) * Np); ScaLBL_AllocateDeviceMemory((void **)&ColorGrad, 3 * sizeof(double) * Np);
//........................................................................... //...........................................................................
// Update GPU data structures // Update GPU data structures
if (rank==0) printf ("Setting up device map and neighbor list \n"); if (rank == 0)
printf("Setting up device map and neighbor list \n");
fflush(stdout); fflush(stdout);
int *TmpMap; int *TmpMap;
TmpMap = new int[Np]; TmpMap = new int[Np];
@ -1180,7 +1303,8 @@ void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest(){
TmpMap[idx] = Nxh * Nyh * Nzh - 1; TmpMap[idx] = Nxh * Nyh * Nzh - 1;
} }
} }
for (int idx=ScaLBL_Comm->FirstInterior(); idx<ScaLBL_Comm->LastInterior(); idx++){ for (int idx = ScaLBL_Comm->FirstInterior();
idx < ScaLBL_Comm->LastInterior(); idx++) {
auto n = TmpMap[idx]; auto n = TmpMap[idx];
if (n > Nxh * Nyh * Nzh) { if (n > Nxh * Nyh * Nzh) {
printf("Bad value! idx=%i \n", n); printf("Bad value! idx=%i \n", n);
@ -1207,12 +1331,18 @@ void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest(){
int x = i - 1; int x = i - 1;
int y = j - 1; int y = j - 1;
int z = k - 1; int z = k - 1;
if (x<0) x=0; if (x < 0)
if (y<0) y=0; x = 0;
if (z<0) z=0; if (y < 0)
if (x>=Nx) x=Nx-1; y = 0;
if (y>=Ny) y=Ny-1; if (z < 0)
if (z>=Nz) z=Nz-1; z = 0;
if (x >= Nx)
x = Nx - 1;
if (y >= Ny)
y = Ny - 1;
if (z >= Nz)
z = Nz - 1;
int n = z * Nx * Ny + y * Nx + x; int n = z * Nx * Ny + y * Nx + x;
phase[nh] = id[n]; phase[nh] = id[n];
} }
@ -1231,9 +1361,12 @@ void ScaLBL_FreeLeeModel::MGTest(){
comm.barrier(); comm.barrier();
ScaLBL_Comm_WideHalo->Send(Phi); ScaLBL_Comm_WideHalo->Send(Phi);
ScaLBL_D3Q9_MGTest(dvcMap,Phi,ColorGrad,Nxh,Nxh*Nyh, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np); ScaLBL_D3Q9_MGTest(dvcMap, Phi, ColorGrad, Nxh, Nxh * Nyh,
ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm_WideHalo->Recv(Phi); ScaLBL_Comm_WideHalo->Recv(Phi);
ScaLBL_D3Q9_MGTest(dvcMap,Phi,ColorGrad,Nxh,Nxh*Nyh, 0, ScaLBL_Comm->LastExterior(), Np); ScaLBL_D3Q9_MGTest(dvcMap, Phi, ColorGrad, Nxh, Nxh * Nyh, 0,
ScaLBL_Comm->LastExterior(), Np);
//check the sum of ColorGrad //check the sum of ColorGrad
double cgx_loc = 0.0; double cgx_loc = 0.0;
@ -1242,8 +1375,10 @@ void ScaLBL_FreeLeeModel::MGTest(){
double cgx, cgy, cgz; double cgx, cgy, cgz;
double *ColorGrad_host; double *ColorGrad_host;
ColorGrad_host = new double[3 * Np]; ColorGrad_host = new double[3 * Np];
ScaLBL_CopyToHost(&ColorGrad_host[0],&ColorGrad[0], 3*Np*sizeof(double)); ScaLBL_CopyToHost(&ColorGrad_host[0], &ColorGrad[0],
for (int i = ScaLBL_Comm->FirstInterior(); i<ScaLBL_Comm->LastInterior();i++){ 3 * Np * sizeof(double));
for (int i = ScaLBL_Comm->FirstInterior(); i < ScaLBL_Comm->LastInterior();
i++) {
cgx_loc += ColorGrad_host[0 * Np + i]; cgx_loc += ColorGrad_host[0 * Np + i];
cgy_loc += ColorGrad_host[1 * Np + i]; cgy_loc += ColorGrad_host[1 * Np + i];
cgz_loc += ColorGrad_host[2 * Np + i]; cgz_loc += ColorGrad_host[2 * Np + i];

View File

@ -101,6 +101,5 @@ private:
//int rank,nprocs; //int rank,nprocs;
void LoadParams(std::shared_ptr<Database> db0); void LoadParams(std::shared_ptr<Database> db0);
void AssignComponentLabels_ChemPotential_ColorGrad(); void AssignComponentLabels_ChemPotential_ColorGrad();
}; };
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,6 @@ Implementation of two-fluid greyscale color lattice boltzmann model
* Mass transport equations are described by D3Q7 scheme * Mass transport equations are described by D3Q7 scheme
*/ */
class ScaLBL_GreyscaleColorModel { class ScaLBL_GreyscaleColorModel {
public: public:
/** /**
@ -90,7 +89,8 @@ public:
double Fx, Fy, Fz, flux; double Fx, Fy, Fz, flux;
double din, dout, inletA, inletB, outletA, outletB; double din, dout, inletA, inletB, outletA, outletB;
double GreyPorosity; double GreyPorosity;
bool RecoloringOff;//recoloring can be turn off for grey nodes if this is true bool
RecoloringOff; //recoloring can be turn off for grey nodes if this is true
//double W;//wetting strength paramter for capillary pressure penalty for grey nodes //double W;//wetting strength paramter for capillary pressure penalty for grey nodes
int Nx, Ny, Nz, N, Np; int Nx, Ny, Nz, N, Np;
@ -161,4 +161,3 @@ private:
*/ */
double SeedPhaseField(const double seed_water_in_oil); double SeedPhaseField(const double seed_water_in_oil);
}; };

View File

@ -22,23 +22,18 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
template<class TYPE> template <class TYPE> void DeleteArray(const TYPE *p) { delete[] p; }
void DeleteArray( const TYPE *p )
{
delete [] p;
}
ScaLBL_GreyscaleModel::ScaLBL_GreyscaleModel(int RANK, int NP, const Utilities::MPI& COMM): ScaLBL_GreyscaleModel::ScaLBL_GreyscaleModel(int RANK, int NP,
rank(RANK), nprocs(NP), Restart(0),timestep(0),timestepMax(0),tau(0),tau_eff(0),Den(0),Fx(0),Fy(0),Fz(0),flux(0),din(0),dout(0),GreyPorosity(0), const Utilities::MPI &COMM)
Nx(0),Ny(0),Nz(0),N(0),Np(0),nprocx(0),nprocy(0),nprocz(0),BoundaryCondition(0),Lx(0),Ly(0),Lz(0),comm(COMM) : rank(RANK), nprocs(NP), Restart(0), timestep(0), timestepMax(0), tau(0),
{ tau_eff(0), Den(0), Fx(0), Fy(0), Fz(0), flux(0), din(0), dout(0),
GreyPorosity(0), Nx(0), Ny(0), Nz(0), N(0), Np(0), nprocx(0), nprocy(0),
nprocz(0), BoundaryCondition(0), Lx(0), Ly(0), Lz(0), comm(COMM) {
SignDist.resize(Nx, Ny, Nz); SignDist.resize(Nx, Ny, Nz);
SignDist.fill(0); SignDist.fill(0);
}
ScaLBL_GreyscaleModel::~ScaLBL_GreyscaleModel(){
} }
ScaLBL_GreyscaleModel::~ScaLBL_GreyscaleModel() {}
void ScaLBL_GreyscaleModel::ReadParams(string filename) { void ScaLBL_GreyscaleModel::ReadParams(string filename) {
// read the input database // read the input database
@ -95,11 +90,11 @@ void ScaLBL_GreyscaleModel::ReadParams(string filename){
if (greyscale_db->keyExists("tolerance")) { if (greyscale_db->keyExists("tolerance")) {
tolerance = greyscale_db->getScalar<double>("tolerance"); tolerance = greyscale_db->getScalar<double>("tolerance");
} }
auto collision = greyscale_db->getWithDefault<std::string>( "collision", "IMRT" ); auto collision =
greyscale_db->getWithDefault<std::string>("collision", "IMRT");
if (collision == "BGK") { if (collision == "BGK") {
CollisionType = 2; CollisionType = 2;
} } else if (collision == "MRT") {
else if (collision == "MRT"){
CollisionType = 3; CollisionType = 3;
} }
// ------------------------------------------------------------------------// // ------------------------------------------------------------------------//
@ -108,16 +103,17 @@ void ScaLBL_GreyscaleModel::ReadParams(string filename){
BoundaryCondition = 0; BoundaryCondition = 0;
if (greyscale_db->keyExists("BC")) { if (greyscale_db->keyExists("BC")) {
BoundaryCondition = greyscale_db->getScalar<int>("BC"); BoundaryCondition = greyscale_db->getScalar<int>("BC");
} } else if (domain_db->keyExists("BC")) {
else if (domain_db->keyExists( "BC" )){
BoundaryCondition = domain_db->getScalar<int>("BC"); BoundaryCondition = domain_db->getScalar<int>("BC");
} }
// ------------------------------------------------------------------------// // ------------------------------------------------------------------------//
} }
void ScaLBL_GreyscaleModel::SetDomain() { void ScaLBL_GreyscaleModel::SetDomain() {
Dm = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // full domain for analysis Dm = std::shared_ptr<Domain>(
Mask = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // mask domain removes immobile phases new Domain(domain_db, comm)); // full domain for analysis
Mask = std::shared_ptr<Domain>(
new Domain(domain_db, comm)); // mask domain removes immobile phases
// domain parameters // domain parameters
Nx = Dm->Nx; Nx = Dm->Nx;
Ny = Dm->Ny; Ny = Dm->Ny;
@ -135,7 +131,8 @@ void ScaLBL_GreyscaleModel::SetDomain(){
Pressure.resize(Nx, Ny, Nz); Pressure.resize(Nx, Ny, Nz);
id = new signed char[N]; id = new signed char[N];
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = 1; // initialize this way for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = 1; // initialize this way
comm.barrier(); comm.barrier();
Dm->CommInit(); Dm->CommInit();
comm.barrier(); comm.barrier();
@ -155,12 +152,14 @@ void ScaLBL_GreyscaleModel::ReadInput(){
if (domain_db->keyExists("Filename")) { if (domain_db->keyExists("Filename")) {
auto Filename = domain_db->getScalar<std::string>("Filename"); auto Filename = domain_db->getScalar<std::string>("Filename");
Mask->Decomp(Filename); Mask->Decomp(Filename);
} } else {
else{ if (rank == 0)
if (rank==0) printf("Filename of input image is not found, reading ID.0* instead."); printf(
"Filename of input image is not found, reading ID.0* instead.");
Mask->ReadIDs(); Mask->ReadIDs();
} }
for (int i=0; i<Nx*Ny*Nz; i++) id[i] = Mask->id[i]; // save what was read for (int i = 0; i < Nx * Ny * Nz; i++)
id[i] = Mask->id[i]; // save what was read
// Generate the signed distance map // Generate the signed distance map
// Initialize the domain and communication // Initialize the domain and communication
@ -172,8 +171,10 @@ void ScaLBL_GreyscaleModel::ReadInput(){
int n = k * Nx * Ny + j * Nx + i; int n = k * Nx * Ny + j * Nx + i;
// Initialize the solid phase // Initialize the solid phase
signed char label = Mask->id[n]; signed char label = Mask->id[n];
if (label > 0) id_solid(i,j,k) = 1; if (label > 0)
else id_solid(i,j,k) = 0; id_solid(i, j, k) = 1;
else
id_solid(i, j, k) = 0;
} }
} }
} }
@ -187,17 +188,20 @@ void ScaLBL_GreyscaleModel::ReadInput(){
} }
} }
// MeanFilter(SignDist); // MeanFilter(SignDist);
if (rank==0) printf("Initialized solid phase -- Converting to Signed Distance function \n"); if (rank == 0)
printf("Initialized solid phase -- Converting to Signed Distance "
"function \n");
CalcDist(SignDist, id_solid, *Mask); CalcDist(SignDist, id_solid, *Mask);
if (rank == 0) cout << "Domain set." << endl; if (rank == 0)
cout << "Domain set." << endl;
} }
/******************************************************** /********************************************************
* AssignComponentLabels * * AssignComponentLabels *
********************************************************/ ********************************************************/
void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Permeability) void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity,
{ double *Permeability) {
size_t NLABELS = 0; size_t NLABELS = 0;
signed char VALUE = 0; signed char VALUE = 0;
double POROSITY = 0.f; double POROSITY = 0.f;
@ -209,7 +213,8 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
NLABELS = LabelList.size(); NLABELS = LabelList.size();
if (NLABELS != PorosityList.size()) { if (NLABELS != PorosityList.size()) {
ERROR("Error: ComponentLabels and PorosityList must be the same length! \n"); ERROR("Error: ComponentLabels and PorosityList must be the same "
"length! \n");
} }
// Assign the labels // Assign the labels
@ -218,7 +223,8 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
label_count = new double[NLABELS]; label_count = new double[NLABELS];
label_count_global = new double[NLABELS]; label_count_global = new double[NLABELS];
for (size_t idx=0; idx<NLABELS; idx++) label_count[idx]=0; for (size_t idx = 0; idx < NLABELS; idx++)
label_count[idx] = 0;
for (int k = 0; k < Nz; k++) { for (int k = 0; k < Nz; k++) {
for (int j = 0; j < Ny; j++) { for (int j = 0; j < Ny; j++) {
@ -238,9 +244,9 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
int idx = Map(i, j, k); int idx = Map(i, j, k);
if (!(idx < 0)) { if (!(idx < 0)) {
if (POROSITY <= 0.0) { if (POROSITY <= 0.0) {
ERROR("Error: Porosity for grey voxels must be 0.0 < Porosity <= 1.0 !\n"); ERROR("Error: Porosity for grey voxels must be 0.0 < "
} "Porosity <= 1.0 !\n");
else{ } else {
Porosity[idx] = POROSITY; Porosity[idx] = POROSITY;
} }
} }
@ -249,7 +255,8 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
} }
if (NLABELS != PermeabilityList.size()) { if (NLABELS != PermeabilityList.size()) {
ERROR("Error: ComponentLabels and PermeabilityList must be the same length! \n"); ERROR("Error: ComponentLabels and PermeabilityList must be the same "
"length! \n");
} }
for (int k = 0; k < Nz; k++) { for (int k = 0; k < Nz; k++) {
for (int j = 0; j < Ny; j++) { for (int j = 0; j < Ny; j++) {
@ -268,25 +275,29 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
int idx = Map(i, j, k); int idx = Map(i, j, k);
if (!(idx < 0)) { if (!(idx < 0)) {
if (PERMEABILITY <= 0.0) { if (PERMEABILITY <= 0.0) {
ERROR("Error: Permeability for grey voxel must be > 0.0 ! \n"); ERROR("Error: Permeability for grey voxel must be > "
} "0.0 ! \n");
else{ } else {
Permeability[idx] = PERMEABILITY/Dm->voxel_length/Dm->voxel_length; Permeability[idx] =
PERMEABILITY / Dm->voxel_length / Dm->voxel_length;
} }
} }
} }
} }
} }
// Set Dm to match Mask // Set Dm to match Mask
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
for (size_t idx=0; idx<NLABELS; idx++) label_count_global[idx]=Dm->Comm.sumReduce( label_count[idx]); for (size_t idx = 0; idx < NLABELS; idx++)
label_count_global[idx] = Dm->Comm.sumReduce(label_count[idx]);
//Initialize a weighted porosity after considering grey voxels //Initialize a weighted porosity after considering grey voxels
GreyPorosity = 0.0; GreyPorosity = 0.0;
for (unsigned int idx = 0; idx < NLABELS; idx++) { for (unsigned int idx = 0; idx < NLABELS; idx++) {
double volume_fraction = double(label_count_global[idx])/double((Nx-2)*(Ny-2)*(Nz-2)*nprocs); double volume_fraction =
double(label_count_global[idx]) /
double((Nx - 2) * (Ny - 2) * (Nz - 2) * nprocs);
GreyPorosity += volume_fraction * PorosityList[idx]; GreyPorosity += volume_fraction * PorosityList[idx];
} }
@ -297,17 +308,27 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
VALUE = LabelList[idx]; VALUE = LabelList[idx];
POROSITY = PorosityList[idx]; POROSITY = PorosityList[idx];
PERMEABILITY = PermeabilityList[idx]; PERMEABILITY = PermeabilityList[idx];
double volume_fraction = double(label_count_global[idx])/double((Nx-2)*(Ny-2)*(Nz-2)*nprocs); double volume_fraction =
printf(" label=%d: porosity=%.3g, permeability=%.3g [um^2] (=%.3g [voxel^2]), volume fraction=%.3g\n", double(label_count_global[idx]) /
VALUE,POROSITY,PERMEABILITY,PERMEABILITY/Dm->voxel_length/Dm->voxel_length,volume_fraction); double((Nx - 2) * (Ny - 2) * (Nz - 2) * nprocs);
printf(" effective porosity=%.3g\n",volume_fraction*POROSITY); printf(" label=%d: porosity=%.3g, permeability=%.3g [um^2] "
"(=%.3g [voxel^2]), volume fraction=%.3g\n",
VALUE, POROSITY, PERMEABILITY,
PERMEABILITY / Dm->voxel_length / Dm->voxel_length,
volume_fraction);
printf(" effective porosity=%.3g\n",
volume_fraction * POROSITY);
} }
printf("The weighted porosity, considering both open and grey voxels, is %.3g\n",GreyPorosity); printf("The weighted porosity, considering both open and grey voxels, "
"is %.3g\n",
GreyPorosity);
} }
} }
void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity,double *Permeability,const vector<std::string> &File_poro,const vector<std::string> &File_perm) void ScaLBL_GreyscaleModel::AssignComponentLabels(
{ double *Porosity, double *Permeability,
const vector<std::string> &File_poro,
const vector<std::string> &File_perm) {
double *Porosity_host, *Permeability_host; double *Porosity_host, *Permeability_host;
Porosity_host = new double[N]; Porosity_host = new double[N];
Permeability_host = new double[N]; Permeability_host = new double[N];
@ -331,12 +352,12 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity,double *Perme
POROSITY = Porosity_host[n]; POROSITY = Porosity_host[n];
PERMEABILITY = Permeability_host[n]; PERMEABILITY = Permeability_host[n];
if (POROSITY <= 0.0) { if (POROSITY <= 0.0) {
ERROR("Error: Porosity for grey voxels must be 0.0 < Porosity <= 1.0 !\n"); ERROR("Error: Porosity for grey voxels must be 0.0 < "
} "Porosity <= 1.0 !\n");
else if (PERMEABILITY<=0.0){ } else if (PERMEABILITY <= 0.0) {
ERROR("Error: Permeability for grey voxel must be > 0.0 ! \n"); ERROR("Error: Permeability for grey voxel must be > "
} "0.0 ! \n");
else{ } else {
Porosity[idx] = POROSITY; Porosity[idx] = POROSITY;
Permeability[idx] = PERMEABILITY; Permeability[idx] = PERMEABILITY;
GreyPorosity_loc += POROSITY; GreyPorosity_loc += POROSITY;
@ -347,11 +368,14 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity,double *Perme
} }
} }
GreyPorosity = Dm->Comm.sumReduce(GreyPorosity_loc); GreyPorosity = Dm->Comm.sumReduce(GreyPorosity_loc);
GreyPorosity = GreyPorosity/double((Nx-2)*(Ny-2)*(Nz-2)*nprocs); GreyPorosity =
GreyPorosity / double((Nx - 2) * (Ny - 2) * (Nz - 2) * nprocs);
if (rank == 0) { if (rank == 0) {
printf("Image resolution: %.5g [um/voxel]\n", Dm->voxel_length); printf("Image resolution: %.5g [um/voxel]\n", Dm->voxel_length);
printf("The weighted porosity, considering both open and grey voxels, is %.3g\n",GreyPorosity); printf("The weighted porosity, considering both open and grey voxels, "
"is %.3g\n",
GreyPorosity);
} }
delete[] Porosity_host; delete[] Porosity_host;
delete[] Permeability_host; delete[] Permeability_host;
@ -368,27 +392,34 @@ void ScaLBL_GreyscaleModel::Create(){
//......................................................... //.........................................................
// Initialize communication structures in averaging domain // Initialize communication structures in averaging domain
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
Mask->CommInit(); Mask->CommInit();
Np = Mask->PoreCount(); Np = Mask->PoreCount();
//........................................................................... //...........................................................................
if (rank==0) printf ("Create ScaLBL_Communicator \n"); if (rank == 0)
printf("Create ScaLBL_Communicator \n");
// Create a communicator for the device (will use optimized layout) // Create a communicator for the device (will use optimized layout)
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original // ScaLBL_Communicator ScaLBL_Comm(Mask); // original
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask)); ScaLBL_Comm =
std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
int Npad = (Np / 16 + 2) * 16; int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N); if (rank == 0)
Map.resize(Nx,Ny,Nz); Map.fill(-2); printf("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx, Ny, Nz);
Map.fill(-2);
auto neighborList = new int[18 * Npad]; auto neighborList = new int[18 * Npad];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1); Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 1);
comm.barrier(); comm.barrier();
//........................................................................... //...........................................................................
// MAIN VARIABLES ALLOCATED HERE // MAIN VARIABLES ALLOCATED HERE
//........................................................................... //...........................................................................
// LBM variables // LBM variables
if (rank==0) printf ("Allocating distributions \n"); if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions................................. //......................device distributions.................................
dist_mem_size = Np * sizeof(double); dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int)); neighborSize = 18 * (Np * sizeof(int));
@ -401,7 +432,8 @@ void ScaLBL_GreyscaleModel::Create(){
ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np); ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np);
//........................................................................... //...........................................................................
// Update GPU data structures // Update GPU data structures
if (rank==0) printf ("Setting up device neighbor list \n"); if (rank == 0)
printf("Setting up device neighbor list \n");
fflush(stdout); fflush(stdout);
// copy the neighbor list // copy the neighbor list
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize); ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
@ -411,16 +443,17 @@ void ScaLBL_GreyscaleModel::Create(){
Perm = new double[Np]; Perm = new double[Np];
if (greyscale_db->keyExists("FileVoxelPorosityMap")) { if (greyscale_db->keyExists("FileVoxelPorosityMap")) {
//NOTE: FileVoxel**Map is a vector, including "file_name, datatype" //NOTE: FileVoxel**Map is a vector, including "file_name, datatype"
auto File_poro = greyscale_db->getVector<std::string>( "FileVoxelPorosityMap" ); auto File_poro =
auto File_perm = greyscale_db->getVector<std::string>( "FileVoxelPermeabilityMap" ); greyscale_db->getVector<std::string>("FileVoxelPorosityMap");
auto File_perm =
greyscale_db->getVector<std::string>("FileVoxelPermeabilityMap");
AssignComponentLabels(Poros, Perm, File_poro, File_perm); AssignComponentLabels(Poros, Perm, File_poro, File_perm);
} } else if (greyscale_db->keyExists("PorosityList")) {
else if (greyscale_db->keyExists("PorosityList")){
//initialize voxel porosity and perm from the input list //initialize voxel porosity and perm from the input list
AssignComponentLabels(Poros, Perm); AssignComponentLabels(Poros, Perm);
} } else {
else { ERROR("Error: PorosityList or FilenameVoxelPorosityMap cannot be "
ERROR("Error: PorosityList or FilenameVoxelPorosityMap cannot be found! \n"); "found! \n");
} }
ScaLBL_CopyToDevice(Porosity, Poros, Np * sizeof(double)); ScaLBL_CopyToDevice(Porosity, Poros, Np * sizeof(double));
ScaLBL_CopyToDevice(Permeability, Perm, Np * sizeof(double)); ScaLBL_CopyToDevice(Permeability, Perm, Np * sizeof(double));
@ -428,26 +461,27 @@ void ScaLBL_GreyscaleModel::Create(){
delete[] Perm; delete[] Perm;
} }
void ScaLBL_GreyscaleModel::Initialize() { void ScaLBL_GreyscaleModel::Initialize() {
if (rank==0) printf ("Initializing distributions \n"); if (rank == 0)
printf("Initializing distributions \n");
//TODO: for BGK, you need to consider voxel porosity //TODO: for BGK, you need to consider voxel porosity
// for IMRT, the whole set of feq is different // for IMRT, the whole set of feq is different
// if in the future you have different collison mode, need to write two set of initialization functions // if in the future you have different collison mode, need to write two set of initialization functions
if (CollisionType == 1) { if (CollisionType == 1) {
ScaLBL_D3Q19_GreyIMRT_Init(fq, Np, Den); ScaLBL_D3Q19_GreyIMRT_Init(fq, Np, Den);
if (rank==0) printf("Collision model: Incompressible MRT.\n"); if (rank == 0)
} printf("Collision model: Incompressible MRT.\n");
else if (CollisionType==2){ } else if (CollisionType == 2) {
ScaLBL_D3Q19_Init(fq, Np); ScaLBL_D3Q19_Init(fq, Np);
if (rank==0) printf("Collision model: BGK.\n"); if (rank == 0)
} printf("Collision model: BGK.\n");
else if (CollisionType==3){ } else if (CollisionType == 3) {
ScaLBL_D3Q19_Init(fq, Np); ScaLBL_D3Q19_Init(fq, Np);
if (rank==0) printf("Collision model: MRT.\n"); if (rank == 0)
} printf("Collision model: MRT.\n");
else{ } else {
if (rank==0) printf("Unknown collison type! IMRT collision is used.\n"); if (rank == 0)
printf("Unknown collison type! IMRT collision is used.\n");
ScaLBL_D3Q19_GreyIMRT_Init(fq, Np, Den); ScaLBL_D3Q19_GreyIMRT_Init(fq, Np, Den);
CollisionType = 1; CollisionType = 1;
greyscale_db->putScalar<std::string>("collision", "IMRT"); greyscale_db->putScalar<std::string>("collision", "IMRT");
@ -482,14 +516,17 @@ void ScaLBL_GreyscaleModel::Run(){
int nprocs = nprocx * nprocy * nprocz; int nprocs = nprocx * nprocy * nprocz;
const RankInfoStruct rank_info(rank, nprocx, nprocy, nprocz); const RankInfoStruct rank_info(rank, nprocx, nprocy, nprocz);
int analysis_interval = 1000; // number of timesteps in between in situ analysis int analysis_interval =
1000; // number of timesteps in between in situ analysis
int visualization_interval = 1000; int visualization_interval = 1000;
int restart_interval = 10000; // number of timesteps in between in saving distributions for restart int restart_interval =
10000; // number of timesteps in between in saving distributions for restart
if (analysis_db->keyExists("analysis_interval")) { if (analysis_db->keyExists("analysis_interval")) {
analysis_interval = analysis_db->getScalar<int>("analysis_interval"); analysis_interval = analysis_db->getScalar<int>("analysis_interval");
} }
if (analysis_db->keyExists("visualization_interval")) { if (analysis_db->keyExists("visualization_interval")) {
visualization_interval = analysis_db->getScalar<int>( "visualization_interval" ); visualization_interval =
analysis_db->getScalar<int>("visualization_interval");
} }
if (analysis_db->keyExists("restart_interval")) { if (analysis_db->keyExists("restart_interval")) {
restart_interval = analysis_db->getScalar<int>("restart_interval"); restart_interval = analysis_db->getScalar<int>("restart_interval");
@ -526,16 +563,28 @@ void ScaLBL_GreyscaleModel::Run(){
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
switch (CollisionType) { switch (CollisionType) {
case 1: case 1:
ScaLBL_D3Q19_AAodd_Greyscale_IMRT(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale_IMRT(
NeighborList, fq, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,
Porosity, Permeability, Velocity, Den, Pressure_dvc);
break; break;
case 2: case 2:
ScaLBL_D3Q19_AAodd_Greyscale(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale(
NeighborList, fq, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,
Porosity, Permeability, Velocity, Pressure_dvc);
break; break;
case 3: case 3:
ScaLBL_D3Q19_AAodd_Greyscale_MRT(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale_MRT(
NeighborList, fq, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,
Porosity, Permeability, Velocity, Den, Pressure_dvc);
break; break;
default: default:
ScaLBL_D3Q19_AAodd_Greyscale_IMRT(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale_IMRT(
NeighborList, fq, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,
Porosity, Permeability, Velocity, Den, Pressure_dvc);
break; break;
} }
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
@ -547,35 +596,60 @@ void ScaLBL_GreyscaleModel::Run(){
} }
switch (CollisionType) { switch (CollisionType) {
case 1: case 1:
ScaLBL_D3Q19_AAodd_Greyscale_IMRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale_IMRT(
NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx,
rlx_eff, Fx, Fy, Fz, Porosity, Permeability, Velocity, Den,
Pressure_dvc);
break; break;
case 2: case 2:
ScaLBL_D3Q19_AAodd_Greyscale(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale(NeighborList, fq, 0,
ScaLBL_Comm->LastExterior(), Np, rlx,
rlx_eff, Fx, Fy, Fz, Porosity,
Permeability, Velocity, Pressure_dvc);
break; break;
case 3: case 3:
ScaLBL_D3Q19_AAodd_Greyscale_MRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale_MRT(
NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx,
rlx_eff, Fx, Fy, Fz, Porosity, Permeability, Velocity, Den,
Pressure_dvc);
break; break;
default: default:
ScaLBL_D3Q19_AAodd_Greyscale_IMRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale_IMRT(
NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx,
rlx_eff, Fx, Fy, Fz, Porosity, Permeability, Velocity, Den,
Pressure_dvc);
break; break;
} }
ScaLBL_DeviceBarrier(); comm.barrier(); ScaLBL_DeviceBarrier();
comm.barrier();
// *************EVEN TIMESTEP*************// // *************EVEN TIMESTEP*************//
timestep++; timestep++;
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
switch (CollisionType) { switch (CollisionType) {
case 1: case 1:
ScaLBL_D3Q19_AAeven_Greyscale_IMRT(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale_IMRT(
fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(),
Np, rlx, rlx_eff, Fx, Fy, Fz, Porosity, Permeability, Velocity,
Den, Pressure_dvc);
break; break;
case 2: case 2:
ScaLBL_D3Q19_AAeven_Greyscale(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale(fq, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np, rlx,
rlx_eff, Fx, Fy, Fz, Porosity,
Permeability, Velocity, Pressure_dvc);
break; break;
case 3: case 3:
ScaLBL_D3Q19_AAeven_Greyscale_MRT(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale_MRT(
fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(),
Np, rlx, rlx_eff, Fx, Fy, Fz, Porosity, Permeability, Velocity,
Den, Pressure_dvc);
break; break;
default: default:
ScaLBL_D3Q19_AAeven_Greyscale_IMRT(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale_IMRT(
fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(),
Np, rlx, rlx_eff, Fx, Fy, Fz, Porosity, Permeability, Velocity,
Den, Pressure_dvc);
break; break;
} }
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
@ -587,19 +661,28 @@ void ScaLBL_GreyscaleModel::Run(){
} }
switch (CollisionType) { switch (CollisionType) {
case 1: case 1:
ScaLBL_D3Q19_AAeven_Greyscale_IMRT(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale_IMRT(
fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy,
Fz, Porosity, Permeability, Velocity, Den, Pressure_dvc);
break; break;
case 2: case 2:
ScaLBL_D3Q19_AAeven_Greyscale(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale(
fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy,
Fz, Porosity, Permeability, Velocity, Pressure_dvc);
break; break;
case 3: case 3:
ScaLBL_D3Q19_AAeven_Greyscale_MRT(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale_MRT(
fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy,
Fz, Porosity, Permeability, Velocity, Den, Pressure_dvc);
break; break;
default: default:
ScaLBL_D3Q19_AAeven_Greyscale_IMRT(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale_IMRT(
fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy,
Fz, Porosity, Permeability, Velocity, Den, Pressure_dvc);
break; break;
} }
ScaLBL_DeviceBarrier(); comm.barrier(); ScaLBL_DeviceBarrier();
comm.barrier();
//************************************************************************/ //************************************************************************/
if (timestep % analysis_interval == 0) { if (timestep % analysis_interval == 0) {
@ -620,17 +703,24 @@ void ScaLBL_GreyscaleModel::Run(){
//parameters for domain average //parameters for domain average
int64_t imin, jmin, kmin, kmax; int64_t imin, jmin, kmin, kmax;
// If external boundary conditions are set, do not average over the inlet and outlet // If external boundary conditions are set, do not average over the inlet and outlet
kmin=1; kmax=Nz-1; kmin = 1;
kmax = Nz - 1;
//In case user forgets to specify the inlet/outlet buffer layers for BC>0 //In case user forgets to specify the inlet/outlet buffer layers for BC>0
if (BoundaryCondition > 0 && Dm->kproc() == 0) kmin=4; if (BoundaryCondition > 0 && Dm->kproc() == 0)
if (BoundaryCondition > 0 && Dm->kproc() == Dm->nprocz()-1) kmax=Nz-4; kmin = 4;
if (BoundaryCondition > 0 && Dm->kproc() == Dm->nprocz() - 1)
kmax = Nz - 4;
imin = jmin = 1; imin = jmin = 1;
// If inlet/outlet layers exist use these as default // If inlet/outlet layers exist use these as default
//if (Dm->inlet_layers_x > 0) imin = Dm->inlet_layers_x; //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_y > 0) jmin = Dm->inlet_layers_y;
if (BoundaryCondition > 0 && Dm->inlet_layers_z > 0 && Dm->kproc() == 0) kmin = 1 + Dm->inlet_layers_z;//"1" indicates the halo layer if (BoundaryCondition > 0 && Dm->inlet_layers_z > 0 &&
if (BoundaryCondition > 0 && Dm->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax = Nz-1 - Dm->outlet_layers_z; Dm->kproc() == 0)
kmin = 1 + Dm->inlet_layers_z; //"1" indicates the halo layer
if (BoundaryCondition > 0 && Dm->outlet_layers_z > 0 &&
Dm->kproc() == Dm->nprocz() - 1)
kmax = Nz - 1 - Dm->outlet_layers_z;
vax_loc = vay_loc = vaz_loc = 0.f; vax_loc = vay_loc = vaz_loc = 0.f;
for (int k = kmin; k < kmax; k++) { for (int k = kmin; k < kmax; k++) {
@ -698,10 +788,14 @@ void ScaLBL_GreyscaleModel::Run(){
WriteHeader = true; WriteHeader = true;
log_file = fopen("Permeability.csv", "a"); log_file = fopen("Permeability.csv", "a");
if (WriteHeader) if (WriteHeader)
fprintf(log_file,"timestep Fx Fy Fz mu Vs As Hs Xs vax vay vaz AbsPerm \n"); fprintf(log_file, "timestep Fx Fy Fz mu Vs As Hs Xs vax "
"vay vaz AbsPerm \n");
fprintf(log_file,"%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g\n",timestep, Fx, Fy, Fz, mu, fprintf(log_file,
h*h*h*Vs,h*h*As,h*Hs,Xs,vax,vay,vaz, absperm); "%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g "
"%.8g %.8g\n",
timestep, Fx, Fy, Fz, mu, h * h * h * Vs, h * h * As,
h * Hs, Xs, vax, vay, vaz, absperm);
fclose(log_file); fclose(log_file);
} }
} }
@ -719,12 +813,14 @@ void ScaLBL_GreyscaleModel::Run(){
std::ofstream OutStream("Restart.db"); std::ofstream OutStream("Restart.db");
current_db->print(OutStream, ""); current_db->print(OutStream, "");
OutStream.close(); OutStream.close();
} }
//Write out Restart data. //Write out Restart data.
std::shared_ptr<double> cfq; std::shared_ptr<double> cfq;
cfq = std::shared_ptr<double>(new double[19*Np],DeleteArray<double>); cfq = std::shared_ptr<double>(new double[19 * Np],
ScaLBL_CopyToHost(cfq.get(),fq,19*Np*sizeof(double));// Copy restart data to the CPU DeleteArray<double>);
ScaLBL_CopyToHost(
cfq.get(), fq,
19 * Np * sizeof(double)); // Copy restart data to the CPU
FILE *RESTARTFILE; FILE *RESTARTFILE;
RESTARTFILE = fopen(LocalRestartFile, "wb"); RESTARTFILE = fopen(LocalRestartFile, "wb");
@ -739,19 +835,26 @@ void ScaLBL_GreyscaleModel::Run(){
//************************************************************************ //************************************************************************
ScaLBL_DeviceBarrier(); ScaLBL_DeviceBarrier();
comm.barrier(); comm.barrier();
if (rank==0) printf("-------------------------------------------------------------------\n"); if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep // Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now(); auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep; double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep;
// Performance obtained from each node // Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000; double MLUPS = double(Np) / cputime / 1000000;
if (rank==0) printf("********************************************************\n"); if (rank == 0)
if (rank==0) printf("CPU time = %f \n", cputime); printf("********************************************************\n");
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS); if (rank == 0)
printf("CPU time = %f \n", cputime);
if (rank == 0)
printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
MLUPS *= nprocs; MLUPS *= nprocs;
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS); if (rank == 0)
if (rank==0) printf("********************************************************\n"); printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
// ************************************************************************ // ************************************************************************
} }
@ -759,7 +862,9 @@ void ScaLBL_GreyscaleModel::Run(){
void ScaLBL_GreyscaleModel::VelocityField() { void ScaLBL_GreyscaleModel::VelocityField() {
std::vector<IO::MeshDataStruct> visData; 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);
auto VxVar = std::make_shared<IO::Variable>(); auto VxVar = std::make_shared<IO::Variable>();
auto VyVar = std::make_shared<IO::Variable>(); auto VyVar = std::make_shared<IO::Variable>();
@ -771,7 +876,9 @@ void ScaLBL_GreyscaleModel::VelocityField(){
// Create the MeshDataStruct // Create the MeshDataStruct
visData.resize(1); visData.resize(1);
visData[0].meshName = "domain"; 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);
SignDistVar->name = "SignDist"; SignDistVar->name = "SignDist";
SignDistVar->type = IO::VariableType::VolumeVariable; SignDistVar->type = IO::VariableType::VolumeVariable;
SignDistVar->dim = 1; SignDistVar->dim = 1;
@ -824,7 +931,6 @@ void ScaLBL_GreyscaleModel::VelocityField(){
fillData.copy(Pressure, PressureData); fillData.copy(Pressure, PressureData);
IO::writeData(timestep, visData, Dm->Comm); IO::writeData(timestep, visData, Dm->Comm);
} }
void ScaLBL_GreyscaleModel::WriteDebug() { void ScaLBL_GreyscaleModel::WriteDebug() {

View File

@ -101,6 +101,7 @@ private:
char LocalRestartFile[40]; char LocalRestartFile[40];
void AssignComponentLabels(double *Porosity, double *Permeablity); void AssignComponentLabels(double *Porosity, double *Permeablity);
void AssignComponentLabels(double *Porosity,double *Permeability,const vector<std::string> &File_poro,const vector<std::string> &File_perm); void AssignComponentLabels(double *Porosity, double *Permeability,
const vector<std::string> &File_poro,
const vector<std::string> &File_perm);
}; };

File diff suppressed because it is too large Load Diff

View File

@ -36,9 +36,12 @@ public:
void Run(double *Velocity, double *ElectricField); void Run(double *Velocity, double *ElectricField);
void getIonConcentration(DoubleArray &IonConcentration, const size_t ic); void getIonConcentration(DoubleArray &IonConcentration, const size_t ic);
void getIonConcentration_debug(int timestep); void getIonConcentration_debug(int timestep);
void getIonFluxDiffusive(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic); void getIonFluxDiffusive(DoubleArray &IonFlux_x, DoubleArray &IonFlux_y,
void getIonFluxAdvective(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic); DoubleArray &IonFlux_z, const size_t ic);
void getIonFluxElectrical(DoubleArray &IonFlux_x,DoubleArray &IonFlux_y,DoubleArray &IonFlux_z,const size_t ic); void getIonFluxAdvective(DoubleArray &IonFlux_x, DoubleArray &IonFlux_y,
DoubleArray &IonFlux_z, const size_t ic);
void getIonFluxElectrical(DoubleArray &IonFlux_x, DoubleArray &IonFlux_y,
DoubleArray &IonFlux_z, const size_t ic);
void getIonFluxDiffusive_debug(int timestep); void getIonFluxDiffusive_debug(int timestep);
void getIonFluxAdvective_debug(int timestep); void getIonFluxAdvective_debug(int timestep);
void getIonFluxElectrical_debug(int timestep); void getIonFluxElectrical_debug(int timestep);
@ -63,8 +66,10 @@ public:
vector<double> IonDiffusivity; //User input unit [m^2/sec] vector<double> IonDiffusivity; //User input unit [m^2/sec]
vector<int> IonValence; vector<int> IonValence;
vector<double> IonConcentration; //unit [mol/m^3] vector<double> IonConcentration; //unit [mol/m^3]
vector<double> Cin;//inlet boundary value, can be either concentration [mol/m^3] or flux [mol/m^2/sec] vector<double>
vector<double> Cout;//outlet boundary value, can be either concentration [mol/m^3] or flux [mol/m^2/sec] Cin; //inlet boundary value, can be either concentration [mol/m^3] or flux [mol/m^2/sec]
vector<double>
Cout; //outlet boundary value, can be either concentration [mol/m^3] or flux [mol/m^2/sec]
vector<double> tau; vector<double> tau;
vector<double> time_conv; vector<double> time_conv;
@ -105,7 +110,9 @@ private:
//int rank,nprocs; //int rank,nprocs;
void LoadParams(std::shared_ptr<Database> db0); void LoadParams(std::shared_ptr<Database> db0);
void AssignSolidBoundary(double *ion_solid); void AssignSolidBoundary(double *ion_solid);
void AssignIonConcentration_FromFile(double *Ci,const vector<std::string> &File_ion,int ic); void AssignIonConcentration_FromFile(double *Ci,
const vector<std::string> &File_ion,
int ic);
void IonConcentration_LB_to_Phys(DoubleArray &Den_reg); void IonConcentration_LB_to_Phys(DoubleArray &Den_reg);
void IonFlux_LB_to_Phys(DoubleArray &Den_reg, const size_t ic); void IonFlux_LB_to_Phys(DoubleArray &Den_reg, const size_t ic);
}; };

View File

@ -20,16 +20,12 @@
#include "models/MRTModel.h" #include "models/MRTModel.h"
#include "analysis/distance.h" #include "analysis/distance.h"
#include "common/ReadMicroCT.h" #include "common/ReadMicroCT.h"
ScaLBL_MRTModel::ScaLBL_MRTModel(int RANK, int NP, const Utilities::MPI& COMM): ScaLBL_MRTModel::ScaLBL_MRTModel(int RANK, int NP, const Utilities::MPI &COMM)
rank(RANK), nprocs(NP), Restart(0),timestep(0),timestepMax(0),tau(0), : rank(RANK), nprocs(NP), Restart(0), timestep(0), timestepMax(0), tau(0),
Fx(0),Fy(0),Fz(0),flux(0),din(0),dout(0),mu(0), Fx(0), Fy(0), Fz(0), flux(0), din(0), dout(0), mu(0), Nx(0), Ny(0), Nz(0),
Nx(0),Ny(0),Nz(0),N(0),Np(0),nprocx(0),nprocy(0),nprocz(0),BoundaryCondition(0),Lx(0),Ly(0),Lz(0),comm(COMM) N(0), Np(0), nprocx(0), nprocy(0), nprocz(0), BoundaryCondition(0), Lx(0),
{ Ly(0), Lz(0), comm(COMM) {}
ScaLBL_MRTModel::~ScaLBL_MRTModel() {}
}
ScaLBL_MRTModel::~ScaLBL_MRTModel(){
}
void ScaLBL_MRTModel::ReadParams(string filename) { void ScaLBL_MRTModel::ReadParams(string filename) {
// read the input database // read the input database
@ -77,16 +73,17 @@ void ScaLBL_MRTModel::ReadParams(string filename){
// Read domain parameters // Read domain parameters
if (mrt_db->keyExists("BoundaryCondition")) { if (mrt_db->keyExists("BoundaryCondition")) {
BoundaryCondition = mrt_db->getScalar<int>("BC"); BoundaryCondition = mrt_db->getScalar<int>("BC");
} } else if (domain_db->keyExists("BC")) {
else if (domain_db->keyExists( "BC" )){
BoundaryCondition = domain_db->getScalar<int>("BC"); BoundaryCondition = domain_db->getScalar<int>("BC");
} }
mu = (tau - 0.5) / 3.0; mu = (tau - 0.5) / 3.0;
} }
void ScaLBL_MRTModel::SetDomain() { void ScaLBL_MRTModel::SetDomain() {
Dm = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // full domain for analysis Dm = std::shared_ptr<Domain>(
Mask = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // mask domain removes immobile phases new Domain(domain_db, comm)); // full domain for analysis
Mask = std::shared_ptr<Domain>(
new Domain(domain_db, comm)); // mask domain removes immobile phases
// domain parameters // domain parameters
Nx = Dm->Nx; Nx = Dm->Nx;
@ -102,7 +99,8 @@ void ScaLBL_MRTModel::SetDomain(){
Velocity_y.resize(Nx, Ny, Nz); Velocity_y.resize(Nx, Ny, Nz);
Velocity_z.resize(Nx, Ny, Nz); Velocity_z.resize(Nx, Ny, Nz);
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = 1; // initialize this way for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = 1; // initialize this way
//Averages = std::shared_ptr<TwoPhase> ( new TwoPhase(Dm) ); // TwoPhase analysis object //Averages = std::shared_ptr<TwoPhase> ( new TwoPhase(Dm) ); // TwoPhase analysis object
comm.barrier(); comm.barrier();
Dm->CommInit(); Dm->CommInit();
@ -120,25 +118,26 @@ void ScaLBL_MRTModel::ReadInput(){
sprintf(LocalRankFilename, "%s%s", "ID.", LocalRankString); sprintf(LocalRankFilename, "%s%s", "ID.", LocalRankString);
sprintf(LocalRestartFile, "%s%s", "Restart.", LocalRankString); sprintf(LocalRestartFile, "%s%s", "Restart.", LocalRankString);
if (domain_db->keyExists("Filename")) { if (domain_db->keyExists("Filename")) {
auto Filename = domain_db->getScalar<std::string>("Filename"); auto Filename = domain_db->getScalar<std::string>("Filename");
Mask->Decomp(Filename); Mask->Decomp(Filename);
} } else if (domain_db->keyExists("GridFile")) {
else if (domain_db->keyExists( "GridFile" )){
// Read the local domain data // Read the local domain data
auto input_id = readMicroCT(*domain_db, comm); auto input_id = readMicroCT(*domain_db, comm);
// Fill the halo (assuming GCW of 1) // Fill the halo (assuming GCW of 1)
array<int,3> size0 = { (int) input_id.size(0), (int) input_id.size(1), (int) input_id.size(2) }; array<int, 3> size0 = {(int)input_id.size(0), (int)input_id.size(1),
ArraySize size1 = { (size_t) Mask->Nx, (size_t) Mask->Ny, (size_t) Mask->Nz }; (int)input_id.size(2)};
ASSERT( (int) size1[0] == size0[0]+2 && (int) size1[1] == size0[1]+2 && (int) size1[2] == size0[2]+2 ); ArraySize size1 = {(size_t)Mask->Nx, (size_t)Mask->Ny,
fillHalo<signed char> fill( comm, Mask->rank_info, size0, { 1, 1, 1 }, 0, 1 ); (size_t)Mask->Nz};
ASSERT((int)size1[0] == size0[0] + 2 && (int)size1[1] == size0[1] + 2 &&
(int)size1[2] == size0[2] + 2);
fillHalo<signed char> fill(comm, Mask->rank_info, size0, {1, 1, 1}, 0,
1);
Array<signed char> id_view; Array<signed char> id_view;
id_view.viewRaw(size1, Mask->id.data()); id_view.viewRaw(size1, Mask->id.data());
fill.copy(input_id, id_view); fill.copy(input_id, id_view);
fill.fill(id_view); fill.fill(id_view);
} } else {
else{
Mask->ReadIDs(); Mask->ReadIDs();
} }
@ -151,8 +150,10 @@ void ScaLBL_MRTModel::ReadInput(){
for (int i = 0; i < Nx; i++) { for (int i = 0; i < Nx; i++) {
int n = k * Nx * Ny + j * Nx + i; int n = k * Nx * Ny + j * Nx + i;
// Initialize the solid phase // Initialize the solid phase
if (Mask->id[n] > 0) id_solid(i,j,k) = 1; if (Mask->id[n] > 0)
else id_solid(i,j,k) = 0; id_solid(i, j, k) = 1;
else
id_solid(i, j, k) = 0;
} }
} }
} }
@ -166,9 +167,12 @@ void ScaLBL_MRTModel::ReadInput(){
} }
} }
// MeanFilter(Averages->SDs); // MeanFilter(Averages->SDs);
if (rank==0) printf("Initialized solid phase -- Converting to Signed Distance function \n"); if (rank == 0)
printf("Initialized solid phase -- Converting to Signed Distance "
"function \n");
CalcDist(Distance, id_solid, *Dm); CalcDist(Distance, id_solid, *Dm);
if (rank == 0) cout << "Domain set." << endl; if (rank == 0)
cout << "Domain set." << endl;
} }
void ScaLBL_MRTModel::Create() { void ScaLBL_MRTModel::Create() {
@ -178,27 +182,34 @@ void ScaLBL_MRTModel::Create(){
int rank = Mask->rank(); int rank = Mask->rank();
//......................................................... //.........................................................
// Initialize communication structures in averaging domain // Initialize communication structures in averaging domain
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i]; for (int i = 0; i < Nx * Ny * Nz; i++)
Dm->id[i] = Mask->id[i];
Mask->CommInit(); Mask->CommInit();
Np = Mask->PoreCount(); Np = Mask->PoreCount();
//........................................................................... //...........................................................................
if (rank==0) printf ("Create ScaLBL_Communicator \n"); if (rank == 0)
printf("Create ScaLBL_Communicator \n");
// Create a communicator for the device (will use optimized layout) // Create a communicator for the device (will use optimized layout)
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original // ScaLBL_Communicator ScaLBL_Comm(Mask); // original
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask)); ScaLBL_Comm =
std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
int Npad = (Np / 16 + 2) * 16; int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout \n"); if (rank == 0)
Map.resize(Nx,Ny,Nz); Map.fill(-2); printf("Set up memory efficient layout \n");
Map.resize(Nx, Ny, Nz);
Map.fill(-2);
auto neighborList = new int[18 * Npad]; auto neighborList = new int[18 * Npad];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1); Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 1);
comm.barrier(); comm.barrier();
//........................................................................... //...........................................................................
// MAIN VARIABLES ALLOCATED HERE // MAIN VARIABLES ALLOCATED HERE
//........................................................................... //...........................................................................
// LBM variables // LBM variables
if (rank==0) printf ("Allocating distributions \n"); if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions................................. //......................device distributions.................................
int dist_mem_size = Np * sizeof(double); int dist_mem_size = Np * sizeof(double);
int neighborSize = 18 * (Np * sizeof(int)); int neighborSize = 18 * (Np * sizeof(int));
@ -209,7 +220,8 @@ void ScaLBL_MRTModel::Create(){
ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np); ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np);
//........................................................................... //...........................................................................
// Update GPU data structures // Update GPU data structures
if (rank==0) printf ("Setting up device map and neighbor list \n"); if (rank == 0)
printf("Setting up device map and neighbor list \n");
// copy the neighbor list // copy the neighbor list
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize); ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
comm.barrier(); comm.barrier();
@ -221,7 +233,8 @@ void ScaLBL_MRTModel::Initialize(){
/* /*
* This function initializes model * This function initializes model
*/ */
if (rank==0) printf ("Initializing distributions \n"); if (rank == 0)
printf("Initializing distributions \n");
ScaLBL_D3Q19_Init(fq, Np); ScaLBL_D3Q19_Init(fq, Np);
} }
@ -247,9 +260,12 @@ void ScaLBL_MRTModel::Run(){
} }
//.......create and start timer............ //.......create and start timer............
ScaLBL_DeviceBarrier(); comm.barrier(); ScaLBL_DeviceBarrier();
if (rank==0) printf("Beginning AA timesteps, timestepMax = %i \n", timestepMax); comm.barrier();
if (rank==0) printf("********************************************************\n"); if (rank == 0)
printf("Beginning AA timesteps, timestepMax = %i \n", timestepMax);
if (rank == 0)
printf("********************************************************\n");
timestep = 0; timestep = 0;
double error = 1.0; double error = 1.0;
double flow_rate_previous = 0.0; double flow_rate_previous = 0.0;
@ -258,47 +274,54 @@ void ScaLBL_MRTModel::Run(){
//************************************************************************/ //************************************************************************/
timestep++; timestep++;
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
ScaLBL_D3Q19_AAodd_MRT(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx_setA, rlx_setB, Fx, Fy, Fz); ScaLBL_D3Q19_AAodd_MRT(NeighborList, fq, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np, rlx_setA,
rlx_setB, Fx, Fy, Fz);
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
// Set boundary conditions // Set boundary conditions
if (BoundaryCondition == 3) { if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
} } else if (BoundaryCondition == 4) {
else if (BoundaryCondition == 4){ din =
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep); ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
} } else if (BoundaryCondition == 5) {
else if (BoundaryCondition == 5){
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq); ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq); ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
} }
ScaLBL_D3Q19_AAodd_MRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx_setA, rlx_setB, Fx, Fy, Fz); ScaLBL_D3Q19_AAodd_MRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(),
ScaLBL_DeviceBarrier(); comm.barrier(); Np, rlx_setA, rlx_setB, Fx, Fy, Fz);
ScaLBL_DeviceBarrier();
comm.barrier();
timestep++; timestep++;
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
ScaLBL_D3Q19_AAeven_MRT(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx_setA, rlx_setB, Fx, Fy, Fz); ScaLBL_D3Q19_AAeven_MRT(fq, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np, rlx_setA,
rlx_setB, Fx, Fy, Fz);
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
// Set boundary conditions // Set boundary conditions
if (BoundaryCondition == 3) { if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
} } else if (BoundaryCondition == 4) {
else if (BoundaryCondition == 4){ din =
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep); ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep); ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
} } else if (BoundaryCondition == 5) {
else if (BoundaryCondition == 5){
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq); ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq); ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
} }
ScaLBL_D3Q19_AAeven_MRT(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx_setA, rlx_setB, Fx, Fy, Fz); ScaLBL_D3Q19_AAeven_MRT(fq, 0, ScaLBL_Comm->LastExterior(), Np,
ScaLBL_DeviceBarrier(); comm.barrier(); rlx_setA, rlx_setB, Fx, Fy, Fz);
ScaLBL_DeviceBarrier();
comm.barrier();
//************************************************************************/ //************************************************************************/
if (timestep % 1000 == 0) { if (timestep % 1000 == 0) {
ScaLBL_D3Q19_Momentum(fq, Velocity, Np); ScaLBL_D3Q19_Momentum(fq, Velocity, Np);
ScaLBL_DeviceBarrier(); comm.barrier(); ScaLBL_DeviceBarrier();
comm.barrier();
ScaLBL_Comm->RegularLayout(Map, &Velocity[0], Velocity_x); ScaLBL_Comm->RegularLayout(Map, &Velocity[0], Velocity_x);
ScaLBL_Comm->RegularLayout(Map, &Velocity[Np], Velocity_y); ScaLBL_Comm->RegularLayout(Map, &Velocity[Np], Velocity_y);
ScaLBL_Comm->RegularLayout(Map, &Velocity[2 * Np], Velocity_z); ScaLBL_Comm->RegularLayout(Map, &Velocity[2 * Np], Velocity_z);
@ -359,31 +382,41 @@ void ScaLBL_MRTModel::Run(){
Xs = Dm->Comm.sumReduce(Xs); Xs = Dm->Comm.sumReduce(Xs);
double h = Dm->voxel_length; double h = Dm->voxel_length;
double absperm = h*h*mu*Mask->Porosity()*flow_rate / force_mag; double absperm =
h * h * mu * Mask->Porosity() * flow_rate / force_mag;
if (rank == 0) { if (rank == 0) {
printf(" %f\n", absperm); printf(" %f\n", absperm);
FILE *log_file = fopen("Permeability.csv", "a"); FILE *log_file = fopen("Permeability.csv", "a");
fprintf(log_file,"%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g\n",timestep, Fx, Fy, Fz, mu, fprintf(log_file,
h*h*h*Vs,h*h*As,h*Hs,Xs,vax,vay,vaz, absperm); "%i %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g %.8g "
"%.8g %.8g\n",
timestep, Fx, Fy, Fz, mu, h * h * h * Vs, h * h * As,
h * Hs, Xs, vax, vay, vaz, absperm);
fclose(log_file); fclose(log_file);
} }
} }
} }
//************************************************************************/ //************************************************************************/
if (rank==0) printf("-------------------------------------------------------------------\n"); if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep // Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now(); auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep; double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep;
// Performance obtained from each node // Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000; double MLUPS = double(Np) / cputime / 1000000;
if (rank==0) printf("********************************************************\n"); if (rank == 0)
if (rank==0) printf("CPU time = %f \n", cputime); printf("********************************************************\n");
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS); if (rank == 0)
printf("CPU time = %f \n", cputime);
if (rank == 0)
printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
MLUPS *= nprocs; MLUPS *= nprocs;
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS); if (rank == 0)
if (rank==0) printf("********************************************************\n"); printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
} }
void ScaLBL_MRTModel::VelocityField() { void ScaLBL_MRTModel::VelocityField() {
@ -432,7 +465,9 @@ void ScaLBL_MRTModel::VelocityField(){
if (vis_db->getWithDefault<bool>("write_silo", false)) { if (vis_db->getWithDefault<bool>("write_silo", false)) {
std::vector<IO::MeshDataStruct> visData; 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);
auto VxVar = std::make_shared<IO::Variable>(); auto VxVar = std::make_shared<IO::Variable>();
auto VyVar = std::make_shared<IO::Variable>(); auto VyVar = std::make_shared<IO::Variable>();
@ -443,7 +478,9 @@ void ScaLBL_MRTModel::VelocityField(){
// Create the MeshDataStruct // Create the MeshDataStruct
visData.resize(1); visData.resize(1);
visData[0].meshName = "domain"; 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);
SignDistVar->name = "SignDist"; SignDistVar->name = "SignDist";
SignDistVar->type = IO::VariableType::VolumeVariable; SignDistVar->type = IO::VariableType::VolumeVariable;
SignDistVar->dim = 1; SignDistVar->dim = 1;

View File

@ -79,6 +79,7 @@ public:
DoubleArray Velocity_x; DoubleArray Velocity_x;
DoubleArray Velocity_y; DoubleArray Velocity_y;
DoubleArray Velocity_z; DoubleArray Velocity_z;
private: private:
Utilities::MPI comm; Utilities::MPI comm;

View File

@ -1,14 +1,11 @@
#include "models/MultiPhysController.h" #include "models/MultiPhysController.h"
ScaLBL_Multiphys_Controller::ScaLBL_Multiphys_Controller(int RANK, int NP, const Utilities::MPI& COMM): ScaLBL_Multiphys_Controller::ScaLBL_Multiphys_Controller(
rank(RANK),nprocs(NP),Restart(0),timestepMax(0),num_iter_Stokes(0),num_iter_Ion(0), int RANK, int NP, const Utilities::MPI &COMM)
analysis_interval(0),visualization_interval(0),tolerance(0),time_conv_max(0),comm(COMM) : rank(RANK), nprocs(NP), Restart(0), timestepMax(0), num_iter_Stokes(0),
{ num_iter_Ion(0), analysis_interval(0), visualization_interval(0),
tolerance(0), time_conv_max(0), comm(COMM) {}
} ScaLBL_Multiphys_Controller::~ScaLBL_Multiphys_Controller() {}
ScaLBL_Multiphys_Controller::~ScaLBL_Multiphys_Controller(){
}
void ScaLBL_Multiphys_Controller::ReadParams(string filename) { void ScaLBL_Multiphys_Controller::ReadParams(string filename) {
@ -16,7 +13,6 @@ void ScaLBL_Multiphys_Controller::ReadParams(string filename){
db = std::make_shared<Database>(filename); db = std::make_shared<Database>(filename);
study_db = db->getDatabase("MultiphysController"); study_db = db->getDatabase("MultiphysController");
// Default parameters // Default parameters
timestepMax = 10000; timestepMax = 10000;
Restart = false; Restart = false;
@ -35,7 +31,8 @@ void ScaLBL_Multiphys_Controller::ReadParams(string filename){
analysis_interval = study_db->getScalar<int>("analysis_interval"); analysis_interval = study_db->getScalar<int>("analysis_interval");
} }
if (study_db->keyExists("visualization_interval")) { if (study_db->keyExists("visualization_interval")) {
visualization_interval = study_db->getScalar<int>( "visualization_interval" ); visualization_interval =
study_db->getScalar<int>("visualization_interval");
} }
if (study_db->keyExists("tolerance")) { if (study_db->keyExists("tolerance")) {
tolerance = study_db->getScalar<double>("tolerance"); tolerance = study_db->getScalar<double>("tolerance");
@ -73,71 +70,88 @@ void ScaLBL_Multiphys_Controller::ReadParams(string filename){
if (study_db->keyExists("num_iter_Stokes")) { if (study_db->keyExists("num_iter_Stokes")) {
num_iter_Stokes = study_db->getScalar<int>("num_iter_Stokes"); num_iter_Stokes = study_db->getScalar<int>("num_iter_Stokes");
} }
} }
int ScaLBL_Multiphys_Controller::getStokesNumIter_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv){ int ScaLBL_Multiphys_Controller::getStokesNumIter_PNP_coupling(
double StokesTimeConv, const vector<double> &IonTimeConv) {
//Return number of internal iterations for the Stokes solver //Return number of internal iterations for the Stokes solver
int num_iter_stokes; int num_iter_stokes;
vector<double> TimeConv; vector<double> TimeConv;
TimeConv.assign(IonTimeConv.begin(), IonTimeConv.end()); TimeConv.assign(IonTimeConv.begin(), IonTimeConv.end());
TimeConv.insert(TimeConv.begin(), StokesTimeConv); TimeConv.insert(TimeConv.begin(), StokesTimeConv);
vector<double>::iterator it_max = max_element(TimeConv.begin(),TimeConv.end()); vector<double>::iterator it_max =
max_element(TimeConv.begin(), TimeConv.end());
int idx_max = distance(TimeConv.begin(), it_max); int idx_max = distance(TimeConv.begin(), it_max);
if (idx_max == 0) { if (idx_max == 0) {
num_iter_stokes = 2; num_iter_stokes = 2;
} } else {
else{ double temp =
double temp = 2*TimeConv[idx_max]/StokesTimeConv;//the factor 2 is the number of iterations for the element has max time_conv 2 * TimeConv[idx_max] /
StokesTimeConv; //the factor 2 is the number of iterations for the element has max time_conv
num_iter_stokes = int(round(temp / 2) * 2); num_iter_stokes = int(round(temp / 2) * 2);
} }
return num_iter_stokes; return num_iter_stokes;
} }
vector<int> ScaLBL_Multiphys_Controller::getIonNumIter_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv){ vector<int> ScaLBL_Multiphys_Controller::getIonNumIter_PNP_coupling(
double StokesTimeConv, const vector<double> &IonTimeConv) {
//Return number of internal iterations for the Ion transport solver //Return number of internal iterations for the Ion transport solver
vector<int> num_iter_ion; vector<int> num_iter_ion;
vector<double> TimeConv; vector<double> TimeConv;
TimeConv.assign(IonTimeConv.begin(), IonTimeConv.end()); TimeConv.assign(IonTimeConv.begin(), IonTimeConv.end());
TimeConv.insert(TimeConv.begin(), StokesTimeConv); TimeConv.insert(TimeConv.begin(), StokesTimeConv);
vector<double>::iterator it_max = max_element(TimeConv.begin(),TimeConv.end()); vector<double>::iterator it_max =
max_element(TimeConv.begin(), TimeConv.end());
unsigned int idx_max = distance(TimeConv.begin(), it_max); unsigned int idx_max = distance(TimeConv.begin(), it_max);
if (idx_max == 0) { if (idx_max == 0) {
for (unsigned int idx = 1; idx < TimeConv.size(); idx++) { for (unsigned int idx = 1; idx < TimeConv.size(); idx++) {
double temp = 2*StokesTimeConv/TimeConv[idx];//the factor 2 is the number of iterations for the element has max time_conv double temp =
2 * StokesTimeConv /
TimeConv
[idx]; //the factor 2 is the number of iterations for the element has max time_conv
num_iter_ion.push_back(int(round(temp / 2) * 2)); num_iter_ion.push_back(int(round(temp / 2) * 2));
} }
} } else if (idx_max == 1) {
else if (idx_max==1){
num_iter_ion.push_back(2); num_iter_ion.push_back(2);
for (unsigned int idx = 2; idx < TimeConv.size(); idx++) { for (unsigned int idx = 2; idx < TimeConv.size(); idx++) {
double temp = 2*TimeConv[idx_max]/TimeConv[idx];//the factor 2 is the number of iterations for the element has max time_conv double temp =
2 * TimeConv[idx_max] /
TimeConv
[idx]; //the factor 2 is the number of iterations for the element has max time_conv
num_iter_ion.push_back(int(round(temp / 2) * 2)); num_iter_ion.push_back(int(round(temp / 2) * 2));
} }
} } else if (idx_max == TimeConv.size() - 1) {
else if (idx_max==TimeConv.size()-1){
for (unsigned int idx = 1; idx < TimeConv.size() - 1; idx++) { for (unsigned int idx = 1; idx < TimeConv.size() - 1; idx++) {
double temp = 2*TimeConv[idx_max]/TimeConv[idx];//the factor 2 is the number of iterations for the element has max time_conv double temp =
2 * TimeConv[idx_max] /
TimeConv
[idx]; //the factor 2 is the number of iterations for the element has max time_conv
num_iter_ion.push_back(int(round(temp / 2) * 2)); num_iter_ion.push_back(int(round(temp / 2) * 2));
} }
num_iter_ion.push_back(2); num_iter_ion.push_back(2);
} } else {
else {
for (unsigned int idx = 1; idx < idx_max; idx++) { for (unsigned int idx = 1; idx < idx_max; idx++) {
double temp = 2*TimeConv[idx_max]/TimeConv[idx];//the factor 2 is the number of iterations for the element has max time_conv double temp =
2 * TimeConv[idx_max] /
TimeConv
[idx]; //the factor 2 is the number of iterations for the element has max time_conv
num_iter_ion.push_back(int(round(temp / 2) * 2)); num_iter_ion.push_back(int(round(temp / 2) * 2));
} }
num_iter_ion.push_back(2); num_iter_ion.push_back(2);
for (unsigned int idx = idx_max + 1; idx < TimeConv.size(); idx++) { for (unsigned int idx = idx_max + 1; idx < TimeConv.size(); idx++) {
double temp = 2*TimeConv[idx_max]/TimeConv[idx];//the factor 2 is the number of iterations for the element has max time_conv double temp =
2 * TimeConv[idx_max] /
TimeConv
[idx]; //the factor 2 is the number of iterations for the element has max time_conv
num_iter_ion.push_back(int(round(temp / 2) * 2)); num_iter_ion.push_back(int(round(temp / 2) * 2));
} }
} }
return num_iter_ion; return num_iter_ion;
} }
void ScaLBL_Multiphys_Controller::getTimeConvMax_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv){ void ScaLBL_Multiphys_Controller::getTimeConvMax_PNP_coupling(
double StokesTimeConv, const vector<double> &IonTimeConv) {
//Return maximum of the time converting factor from Stokes and ion solvers //Return maximum of the time converting factor from Stokes and ion solvers
vector<double> TimeConv; vector<double> TimeConv;

View File

@ -24,10 +24,13 @@ public:
void ReadParams(string filename); void ReadParams(string filename);
void ReadParams(std::shared_ptr<Database> db0); void ReadParams(std::shared_ptr<Database> db0);
int getStokesNumIter_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv); int getStokesNumIter_PNP_coupling(double StokesTimeConv,
vector<int> getIonNumIter_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv); const vector<double> &IonTimeConv);
vector<int> getIonNumIter_PNP_coupling(double StokesTimeConv,
const vector<double> &IonTimeConv);
//void getIonNumIter_PNP_coupling(double StokesTimeConv,vector<double> &IonTimeConv,vector<int> &IonTimeMax); //void getIonNumIter_PNP_coupling(double StokesTimeConv,vector<double> &IonTimeConv,vector<int> &IonTimeMax);
void getTimeConvMax_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv); void getTimeConvMax_PNP_coupling(double StokesTimeConv,
const vector<double> &IonTimeConv);
bool Restart; bool Restart;
int timestepMax; int timestepMax;

Some files were not shown because too many files have changed in this diff Show More