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:
# cd to root directory
# To update format only:
# find . -name "*.cpp" -or -name "*.cc" -or -name "*.h" -or -name "*.hpp" -or -name "*.I" | xargs -I{} clang-format -i {}
# git status -s . | sed s/^...// | grep -E "(\.cpp|\.h|\.cc|\.hpp|\.I)" | xargs -I{} clang-format -i {}
# To run modernize
# export CLANG_PATH=/packages/llvm/build/llvm-60
# export PATH=${CLANG_PATH}/bin:${CLANG_PATH}/share/clang:$PATH
# find src -name "*.cpp" -or -name "*.cc" | xargs -I{} clang-tidy -checks=modernize* -p=/projects/AtomicModel/build/debug -fix {}
# find src -name "*.cpp" -or -name "*.cc" -or -name "*.h" -or -name "*.hpp" -or -name "*.I" | xargs -I{} clang-format -i {}
# clang-format
---
Language: Cpp
# BasedOnStyle: LLVM
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
#BreakBeforeBraces: Stroustrup
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: true
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never
...
# Our includes are not order-agnostic
SortIncludes: false
# Some of our comments include insightful insight
ReflowComments: false
...

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -53,10 +53,10 @@ public:
void SetParams();
void Basic(ScaLBL_FreeLeeModel &LeeModel, int timestep);
void WriteVis( ScaLBL_FreeLeeModel &LeeModel, std::shared_ptr<Database> input_db, int timestep);
void WriteVis(ScaLBL_FreeLeeModel &LeeModel,
std::shared_ptr<Database> input_db, int timestep);
private:
FILE *TIMELOG;
};
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,6 @@
#include "IO/Reader.h"
#include "IO/Writer.h"
class phase {
public:
int Nc;
@ -86,7 +85,8 @@ public:
IntArray PhaseID; // Phase ID array (solid=0, non-wetting=1, wetting=2)
BlobIDArray Label_WP; // Wetting phase label
BlobIDArray Label_NWP; // Non-wetting phase label index (0:nblobs-1)
std::vector<BlobIDType> Label_NWP_map; // Non-wetting phase label for each index
std::vector<BlobIDType>
Label_NWP_map; // Non-wetting phase label for each index
DoubleArray Rho_n; // density field
DoubleArray Rho_w; // density field
DoubleArray Phi; // phase indicator field
@ -105,7 +105,9 @@ public:
SubPhase(std::shared_ptr<Domain> Dm);
~SubPhase();
void SetParams(double rhoA, double rhoB, double tauA, double tauB, double force_x, double force_y, double force_z, double alpha, double beta);
void SetParams(double rhoA, double rhoB, double tauA, double tauB,
double force_x, double force_y, double force_z, double alpha,
double beta);
void Basic();
void Full();
void Write(int time);
@ -117,4 +119,3 @@ private:
};
#endif

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -34,7 +34,6 @@ private:
std::vector<Point> d_data;
};
/**
* \class Halfedge
* @brief store half edge for DCEL data structure
@ -75,7 +74,8 @@ public:
int face();
Vertex vertex;
Halfedge halfedge;
void LocalIsosurface(const DoubleArray& A, double value, int i, int j, int k);
void LocalIsosurface(const DoubleArray &A, double value, int i, int j,
int k);
void Write();
int Face(int index);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,14 +22,11 @@
#include "common/Array.h"
#include <vector>
namespace imfilter {
//! enum to store the BC type
enum class BC { fixed = 0, symmetric = 1, replicate = 2, circular = 3 };
/*!
* @brief N-D filtering of multidimensional images
* @details imfilter filters the multidimensional array A with the
@ -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)
*/
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
@ -73,8 +71,8 @@ Array<TYPE> imfilter( const Array<TYPE>& A, const Array<TYPE>& H, const std::vec
template <class TYPE>
Array<TYPE> imfilter(const Array<TYPE> &A, const std::vector<int> &Nh,
std::function<TYPE(const Array<TYPE> &)> H,
const std::vector<imfilter::BC>& boundary, const TYPE X=0 );
const std::vector<imfilter::BC> &boundary,
const TYPE X = 0);
/*!
* @brief N-D filtering of multidimensional images
@ -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)
*/
template <class TYPE>
Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<Array<TYPE>>& H,
Array<TYPE>
imfilter_separable(const Array<TYPE> &A, const std::vector<Array<TYPE>> &H,
const std::vector<imfilter::BC> &boundary, const TYPE X = 0);
/*!
* @brief N-D filtering of multidimensional images
* @details imfilter filters the multidimensional array A with the
@ -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)
*/
template <class TYPE>
Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<int>& Nh,
Array<TYPE>
imfilter_separable(const Array<TYPE> &A, const std::vector<int> &Nh,
std::vector<std::function<TYPE(const Array<TYPE> &)>> H,
const std::vector<imfilter::BC> &boundary, const TYPE X = 0);
/*!
* @brief N-D filtering of multidimensional images
* @details imfilter filters the multidimensional array A with the
@ -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)
*/
template <class TYPE>
Array<TYPE> imfilter_separable( const Array<TYPE>& A, const std::vector<int>& Nh,
Array<TYPE>
imfilter_separable(const Array<TYPE> &A, const std::vector<int> &Nh,
std::vector<std::function<TYPE(int, const TYPE *)>> H,
const std::vector<imfilter::BC> &boundary, const TYPE X = 0);
/**
* @brief Create a filter to use with imfilter
* @details This function creates one of several predefined filters
@ -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
*/
template <class TYPE>
Array<TYPE> create_filter( const std::vector<int>& N, const std::string &type, const void *args = NULL );
}
Array<TYPE> create_filter(const std::vector<int> &N, const std::string &type,
const void *args = NULL);
} // namespace imfilter
#include "analysis/imfilter.hpp"
#endif

View File

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

View File

@ -1,7 +1,8 @@
#include <analysis/morphology.h>
// Implementation of morphological opening routine
inline void PackID(const int *list, int count, signed char *sendbuf, signed char *ID){
inline void PackID(const int *list, int count, signed char *sendbuf,
signed char *ID) {
// Fill in the phase ID values from neighboring processors
// This packs up the values that need to be sent from one processor to another
int idx, n;
@ -13,7 +14,8 @@ inline void PackID(const int *list, int count, signed char *sendbuf, signed char
}
//***************************************************************************************
inline void UnpackID(const int *list, int count, signed char *recvbuf, signed char *ID){
inline void UnpackID(const int *list, int count, signed char *recvbuf,
signed char *ID) {
// Fill in the phase ID values from neighboring processors
// This unpacks the values once they have been recieved from neighbors
int idx, n;
@ -30,9 +32,7 @@ Morphology::Morphology(){
sendtag = recvtag = 1381;
}
Morphology::~Morphology(){
}
Morphology::~Morphology() {}
void Morphology::Initialize(std::shared_ptr<Domain> Dm, DoubleArray &Distance) {
/* Loop over all faces and determine overlaps */
@ -89,7 +89,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
morphRadius.resize(recvLoc);
//..............................
/* send the morphological radius */
Dm->Comm.Irecv(&morphRadius[recvOffset_X],recvCount,Dm->rank_X(),recvtag+0);
Dm->Comm.Irecv(&morphRadius[recvOffset_X], recvCount, Dm->rank_X(),
recvtag + 0);
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_x(), sendtag + 0);
/* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_X], recvCount, Dm->rank_X(), recvtag + 1);
@ -136,7 +137,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
morphRadius.resize(recvLoc);
//..............................
/* send the morphological radius */
Dm->Comm.Irecv(&morphRadius[recvOffset_x],recvCount,Dm->rank_x(),recvtag+0);
Dm->Comm.Irecv(&morphRadius[recvOffset_x], recvCount, Dm->rank_x(),
recvtag + 0);
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_X(), sendtag + 0);
/* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_x], recvCount, Dm->rank_x(), recvtag + 1);
@ -184,7 +186,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
morphRadius.resize(recvLoc);
//..............................
/* send the morphological radius */
Dm->Comm.Irecv(&morphRadius[recvOffset_Y],recvCount,Dm->rank_Y(),recvtag+0);
Dm->Comm.Irecv(&morphRadius[recvOffset_Y], recvCount, Dm->rank_Y(),
recvtag + 0);
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_y(), sendtag + 0);
/* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_Y], recvCount, Dm->rank_Y(), recvtag + 1);
@ -231,7 +234,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
morphRadius.resize(recvLoc);
//..............................
/* send the morphological radius */
Dm->Comm.Irecv(&morphRadius[recvOffset_y],recvCount,Dm->rank_y(),recvtag+0);
Dm->Comm.Irecv(&morphRadius[recvOffset_y], recvCount, Dm->rank_y(),
recvtag + 0);
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_Y(), sendtag + 0);
/* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_y], recvCount, Dm->rank_y(), recvtag + 1);
@ -279,7 +283,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
morphRadius.resize(recvLoc);
//..............................
/* send the morphological radius */
Dm->Comm.Irecv(&morphRadius[recvOffset_Z],recvCount,Dm->rank_Z(),recvtag+0);
Dm->Comm.Irecv(&morphRadius[recvOffset_Z], recvCount, Dm->rank_Z(),
recvtag + 0);
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_z(), sendtag + 0);
/* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_Z], recvCount, Dm->rank_Z(), recvtag + 1);
@ -325,7 +330,8 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
morphRadius.resize(recvLoc);
//..............................
/* send the morphological radius */
Dm->Comm.Irecv(&morphRadius[recvOffset_z],recvCount,Dm->rank_z(),recvtag+0);
Dm->Comm.Irecv(&morphRadius[recvOffset_z], recvCount, Dm->rank_z(),
recvtag + 0);
Dm->Comm.send(&tmpDistance[0], sendCount, Dm->rank_Z(), sendtag + 0);
/* send the shift values */
Dm->Comm.Irecv(&xShift[recvOffset_z], recvCount, Dm->rank_z(), recvtag + 1);
@ -352,10 +358,11 @@ void Morphology::Initialize(std::shared_ptr <Domain> Dm, DoubleArray &Distance){
printf(" offset %i for send (z) %i \n", sendOffset_z, sendCount_z);
printf(" offset %i for send (Z) %i \n", sendOffset_Z, sendCount_Z);
*/
}
int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const signed char ErodeLabel, const signed char NewLabel){
int Morphology::GetOverlaps(std::shared_ptr<Domain> Dm, signed char *id,
const signed char ErodeLabel,
const signed char NewLabel) {
int Nx = Dm->Nx;
int Ny = Dm->Ny;
@ -369,28 +376,40 @@ int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const
localID[idx] = id[n];
}
//printf("send x -- offset: %i, count: %i \n",sendOffset_x,sendCount_x);
Dm->Comm.Irecv(&nonlocalID[recvOffset_X],recvCount_X,Dm->rank_x(),recvtag+2);
Dm->Comm.send(&localID[sendOffset_x],sendCount_x,Dm->rank_X(),sendtag+2);
Dm->Comm.Irecv(&nonlocalID[recvOffset_X], recvCount_X, Dm->rank_x(),
recvtag + 2);
Dm->Comm.send(&localID[sendOffset_x], sendCount_x, Dm->rank_X(),
sendtag + 2);
//printf("send X \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_x],recvCount_x,Dm->rank_X(),recvtag+3);
Dm->Comm.send(&localID[sendOffset_X],sendCount_X,Dm->rank_x(),sendtag+3);
Dm->Comm.Irecv(&nonlocalID[recvOffset_x], recvCount_x, Dm->rank_X(),
recvtag + 3);
Dm->Comm.send(&localID[sendOffset_X], sendCount_X, Dm->rank_x(),
sendtag + 3);
//printf("send y \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_Y],recvCount_Y,Dm->rank_y(),recvtag+4);
Dm->Comm.send(&localID[sendOffset_y],sendCount_y,Dm->rank_Y(),sendtag+4);
Dm->Comm.Irecv(&nonlocalID[recvOffset_Y], recvCount_Y, Dm->rank_y(),
recvtag + 4);
Dm->Comm.send(&localID[sendOffset_y], sendCount_y, Dm->rank_Y(),
sendtag + 4);
//printf("send Y \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_y],recvCount_y,Dm->rank_Y(),recvtag+5);
Dm->Comm.send(&localID[sendOffset_Y],sendCount_Y,Dm->rank_y(),sendtag+5);
Dm->Comm.Irecv(&nonlocalID[recvOffset_y], recvCount_y, Dm->rank_Y(),
recvtag + 5);
Dm->Comm.send(&localID[sendOffset_Y], sendCount_Y, Dm->rank_y(),
sendtag + 5);
//printf("send z \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_Z],recvCount_Z,Dm->rank_z(),recvtag+6);
Dm->Comm.send(&localID[sendOffset_z],sendCount_z,Dm->rank_Z(),sendtag+6);
Dm->Comm.Irecv(&nonlocalID[recvOffset_Z], recvCount_Z, Dm->rank_z(),
recvtag + 6);
Dm->Comm.send(&localID[sendOffset_z], sendCount_z, Dm->rank_Z(),
sendtag + 6);
//printf("send Z \n");
Dm->Comm.Irecv(&nonlocalID[recvOffset_z],recvCount_z,Dm->rank_Z(),recvtag+7);
Dm->Comm.send(&localID[sendOffset_Z],sendCount_Z,Dm->rank_z(),sendtag+7);
Dm->Comm.Irecv(&nonlocalID[recvOffset_z], recvCount_z, Dm->rank_Z(),
recvtag + 7);
Dm->Comm.send(&localID[sendOffset_Z], sendCount_Z, Dm->rank_z(),
sendtag + 7);
for (int idx = 0; idx < recvCount; idx++) {
double radius = morphRadius[idx];
@ -412,7 +431,9 @@ int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const
for (jj = jmin; jj < jmax; jj++) {
for (ii = imin; ii < imax; ii++) {
int nn = kk * Nx * Ny + jj * Nx + ii;
double dsq = double((ii-i)*(ii-i)+(jj-j)*(jj-j)+(kk-k)*(kk-k));
double dsq =
double((ii - i) * (ii - i) + (jj - j) * (jj - j) +
(kk - k) * (kk - k));
if (id[nn] == ErodeLabel && dsq <= radius * radius) {
LocalNumber += 1.0;
id[nn] = NewLabel;
@ -428,7 +449,9 @@ int Morphology::GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const
}
//***************************************************************************************
double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction, signed char ErodeLabel, signed char NewLabel){
double MorphOpen(DoubleArray &SignDist, signed char *id,
std::shared_ptr<Domain> Dm, double VoidFraction,
signed char ErodeLabel, signed char NewLabel) {
// SignDist is the distance to the object that you want to constaing the morphological opening
// VoidFraction is the the empty space where the object inst
// id is a labeled map
@ -453,7 +476,8 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
for (int i = 1; i < nx - 1; i++) {
n = k * nx * ny + j * nx + i;
// extract maximum distance for critical radius
if ( SignDist(i,j,k) > maxdist) maxdist=SignDist(i,j,k);
if (SignDist(i, j, k) > maxdist)
maxdist = SignDist(i, j, k);
if (id[n] == ErodeLabel) {
count += 1.0;
//id[n] = 2;
@ -469,10 +493,14 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
// total Global is the number of nodes in the pore-space
totalGlobal = Dm->Comm.sumReduce(count);
maxdistGlobal = Dm->Comm.sumReduce(maxdist);
double volume=double(nprocx*nprocy*nprocz)*double(nx-2)*double(ny-2)*double(nz-2);
double volume = double(nprocx * nprocy * nprocz) * double(nx - 2) *
double(ny - 2) * double(nz - 2);
double volume_fraction = totalGlobal / volume;
if (rank==0) printf("Volume fraction for morphological opening: %f \n",volume_fraction);
if (rank==0) printf("Maximum pore size: %f \n",maxdistGlobal);
if (rank == 0)
printf("Volume fraction for morphological opening: %f \n",
volume_fraction);
if (rank == 0)
printf("Maximum pore size: %f \n", maxdistGlobal);
final_void_fraction = volume_fraction; //initialize
int ii, jj, kk;
@ -496,8 +524,7 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
int numTry = 0;
int maxTry = 100;
while (void_fraction_new > VoidFraction && numTry < maxTry)
{
while (void_fraction_new > VoidFraction && numTry < maxTry) {
numTry++;
void_fraction_diff_old = void_fraction_diff_new;
void_fraction_old = void_fraction_new;
@ -507,7 +534,9 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
numTry = maxTry;
}
int Window = round(Rcrit_new);
if (Window == 0) Window = 1; // If Window = 0 at the begining, after the following process will have sw=1.0
if (Window == 0)
Window =
1; // If Window = 0 at the begining, after the following process will have sw=1.0
// and sw<Sw will be immediately broken
double LocalNumber = 0.f;
for (int k = 0; k < Nz; k++) {
@ -526,15 +555,17 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
for (jj = jmin; jj < jmax; jj++) {
for (ii = imin; ii < imax; ii++) {
int nn = kk * nx * ny + jj * nx + ii;
double dsq = double((ii-i)*(ii-i)+(jj-j)*(jj-j)+(kk-k)*(kk-k));
if (id[nn] == ErodeLabel && dsq <= Rcrit_new*Rcrit_new){
double dsq = double((ii - i) * (ii - i) +
(jj - j) * (jj - j) +
(kk - k) * (kk - k));
if (id[nn] == ErodeLabel &&
dsq <= Rcrit_new * Rcrit_new) {
LocalNumber += 1.0;
id[nn] = NewLabel;
}
}
}
}
}
// move on
}
@ -568,8 +599,7 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
printf("Final void fraction =%f\n", void_fraction_new);
printf("Final critical radius=%f\n", Rcrit_new);
}
}
else{
} else {
final_void_fraction = void_fraction_old;
if (rank == 0) {
printf("Final void fraction=%f\n", void_fraction_old);
@ -579,9 +609,9 @@ double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain>
return final_void_fraction;
}
//***************************************************************************************
double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction){
double MorphDrain(DoubleArray &SignDist, signed char *id,
std::shared_ptr<Domain> Dm, double VoidFraction) {
// SignDist is the distance to the object that you want to constaing the morphological opening
// VoidFraction is the the empty space where the object inst
// id is a labeled map
@ -601,7 +631,8 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
DoubleArray phase(nx, ny, nz);
IntArray phase_label(nx, ny, nz);
Array<char> ID(nx, ny, nz);
fillHalo<char> fillChar(Dm->Comm,Dm->rank_info,{nx-2,ny-2,nz-2},{1,1,1},0,1);
fillHalo<char> fillChar(Dm->Comm, Dm->rank_info, {nx - 2, ny - 2, nz - 2},
{1, 1, 1}, 0, 1);
Morphology Structure;
Structure.Initialize(Dm, SignDist);
@ -617,7 +648,8 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
for (int i = 1; i < nx - 1; i++) {
n = k * nx * ny + j * nx + i;
// extract maximum distance for critical radius
if ( SignDist(i,j,k) > maxdist) maxdist=SignDist(i,j,k);
if (SignDist(i, j, k) > maxdist)
maxdist = SignDist(i, j, k);
if (SignDist(i, j, k) > 0.0) {
count += 1.0;
id[n] = ErodeLabel;
@ -632,10 +664,14 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
// total Global is the number of nodes in the pore-space
totalGlobal = Dm->Comm.sumReduce(count);
maxdistGlobal = Dm->Comm.sumReduce(maxdist);
double volume=double(nprocx*nprocy*nprocz)*double(nx-2)*double(ny-2)*double(nz-2);
double volume = double(nprocx * nprocy * nprocz) * double(nx - 2) *
double(ny - 2) * double(nz - 2);
double volume_fraction = totalGlobal / volume;
if (rank==0) printf("Volume fraction for morphological opening: %f \n",volume_fraction);
if (rank==0) printf("Maximum pore size: %f \n",maxdistGlobal);
if (rank == 0)
printf("Volume fraction for morphological opening: %f \n",
volume_fraction);
if (rank == 0)
printf("Maximum pore size: %f \n", maxdistGlobal);
int ii, jj, kk;
int imin, jmin, kmin, imax, jmax, kmax;
@ -661,14 +697,15 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
FILE *DRAIN = fopen("morphdrain.csv", "w");
fprintf(DRAIN, "sw radius\n");
while (void_fraction_new > VoidFraction && Rcrit_new > 0.5)
{
while (void_fraction_new > VoidFraction && Rcrit_new > 0.5) {
void_fraction_diff_old = void_fraction_diff_new;
void_fraction_old = void_fraction_new;
Rcrit_old = Rcrit_new;
Rcrit_new -= deltaR * Rcrit_old;
int Window = round(Rcrit_new);
if (Window == 0) Window = 1; // If Window = 0 at the begining, after the following process will have sw=1.0
if (Window == 0)
Window =
1; // If Window = 0 at the begining, after the following process will have sw=1.0
// and sw<Sw will be immediately broken
double LocalNumber = 0.f;
for (int k = 1; k < Nz - 1; k++) {
@ -686,12 +723,17 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
for (kk = kmin; kk < kmax; kk++) {
for (jj = jmin; jj < jmax; jj++) {
for (ii = imin; ii < imax; ii++) {
double dsq = double((ii-i)*(ii-i)+(jj-j)*(jj-j)+(kk-k)*(kk-k));
if (ID(ii,jj,kk) == ErodeLabel && dsq <= (Rcrit_new+1)*(Rcrit_new+1)){
double dsq = double((ii - i) * (ii - i) +
(jj - j) * (jj - j) +
(kk - k) * (kk - k));
if (ID(ii, jj, kk) == ErodeLabel &&
dsq <=
(Rcrit_new + 1) * (Rcrit_new + 1)) {
LocalNumber += 1.0;
//id[nn]=1;
ID(ii, jj, kk) = NewLabel;
id[kk*Nx*Ny+jj*Nx+ii] = NewLabel;
id[kk * Nx * Ny + jj * Nx + ii] =
NewLabel;
}
}
}
@ -718,16 +760,17 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
for (int i = 0; i < nx; i++) {
if (ID(i, j, k) == NewLabel) {
phase(i, j, k) = 1.0;
}
else
} else
phase(i, j, k) = -1.0;
}
}
}
// Extract only the connected part of NWP
double vF=0.0; double vS=0.0;
ComputeGlobalBlobIDs(nx-2,ny-2,nz-2,Dm->rank_info,phase,SignDist,vF,vS,phase_label,Dm->Comm);
double vF = 0.0;
double vS = 0.0;
ComputeGlobalBlobIDs(nx - 2, ny - 2, nz - 2, Dm->rank_info, phase,
SignDist, vF, vS, phase_label, Dm->Comm);
Dm->Comm.barrier();
for (int k = 0; k < nz; k++) {
@ -770,8 +813,7 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
printf("Final void fraction =%f\n", void_fraction_new);
printf("Final critical radius=%f\n", Rcrit_new);
}
}
else{
} else {
final_void_fraction = void_fraction_old;
if (rank == 0) {
printf("Final void fraction=%f\n", void_fraction_old);
@ -794,8 +836,9 @@ double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain
}
//double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id, std::shared_ptr<Domain> Dm, double TargetGrowth)
double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id, std::shared_ptr<Domain> Dm, double TargetGrowth, double WallFactor)
{
double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
std::shared_ptr<Domain> Dm, double TargetGrowth,
double WallFactor) {
int Nx = Dm->Nx;
int Ny = Dm->Ny;
int Nz = Dm->Nz;
@ -815,14 +858,17 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
// Estimate morph_delta
double morph_delta = 0.0;
if (TargetGrowth > 0.0) morph_delta = 0.1;
else morph_delta = -0.1;
if (TargetGrowth > 0.0)
morph_delta = 0.1;
else
morph_delta = -0.1;
double morph_delta_previous = 0.0;
double GrowthEstimate = 0.0;
double GrowthPrevious = 0.0;
int COUNT_FOR_LOOP = 0;
double ERROR = 100.0;
if (rank == 0) printf("Estimate delta for growth=%f \n",TargetGrowth);
if (rank == 0)
printf("Estimate delta for growth=%f \n", TargetGrowth);
while (ERROR > 0.01 && COUNT_FOR_LOOP < 10) {
COUNT_FOR_LOOP++;
count = 0.0;
@ -832,9 +878,11 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
for (int i = 1; i < Nx - 1; i++) {
double walldist = BoundaryDist(i, j, k);
//double wallweight = 1.0 / (1+exp(-5.f*(walldist-1.f)));
double wallweight = WallFactor/ (1+exp(-5.f*(walldist-1.f)));
double wallweight =
WallFactor / (1 + exp(-5.f * (walldist - 1.f)));
//wallweight = 1.0;
if (fabs(wallweight*morph_delta) > MAX_DISPLACEMENT) MAX_DISPLACEMENT= fabs(wallweight*morph_delta);
if (fabs(wallweight * morph_delta) > MAX_DISPLACEMENT)
MAX_DISPLACEMENT = fabs(wallweight * morph_delta);
if (Dist(i, j, k) - wallweight * morph_delta < 0.0) {
count += 1.0;
@ -847,15 +895,20 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
GrowthEstimate = count - count_original;
ERROR = fabs((GrowthEstimate - TargetGrowth) / TargetGrowth);
if (rank == 0) printf(" delta=%f, growth=%f, max. displacement = %f \n",morph_delta, GrowthEstimate, MAX_DISPLACEMENT);
if (rank == 0)
printf(" delta=%f, growth=%f, max. displacement = %f \n",
morph_delta, GrowthEstimate, MAX_DISPLACEMENT);
// Now adjust morph_delta
if (fabs(GrowthEstimate - GrowthPrevious) > 0.0) {
double step_size = (TargetGrowth - GrowthEstimate)*(morph_delta - morph_delta_previous) / (GrowthEstimate - GrowthPrevious);
double step_size = (TargetGrowth - GrowthEstimate) *
(morph_delta - morph_delta_previous) /
(GrowthEstimate - GrowthPrevious);
GrowthPrevious = GrowthEstimate;
morph_delta_previous = morph_delta;
morph_delta += step_size;
}
if (morph_delta / morph_delta_previous > 2.0 ) morph_delta = morph_delta_previous*2.0;
if (morph_delta / morph_delta_previous > 2.0)
morph_delta = morph_delta_previous * 2.0;
//MAX_DISPLACEMENT *= max(TargetGrowth/GrowthEstimate,1.25);
@ -865,8 +918,7 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
morph_delta = 3.0;
COUNT_FOR_LOOP = 100; // exit loop if displacement is too large
}
}
else{
} else {
// object is shrinking
if (MAX_DISPLACEMENT > 1.0) {
morph_delta = -1.0;
@ -874,7 +926,8 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
}
}
}
if (rank == 0) printf("Final delta=%f \n",morph_delta);
if (rank == 0)
printf("Final delta=%f \n", morph_delta);
count = 0.0;
for (int k = 1; k < Nz - 1; k++) {
@ -883,10 +936,12 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
double walldist = BoundaryDist(i, j, k);
//double wallweight = 1.0 / (1+exp(-5.f*(walldist-1.f)));
//wallweight = 1.0;
double wallweight = WallFactor / (1+exp(-5.f*(walldist-1.f)));
double wallweight =
WallFactor / (1 + exp(-5.f * (walldist - 1.f)));
Dist(i, j, k) -= wallweight * morph_delta;
if (Dist(i,j,k) < 0.0) count+=1.0;
if (Dist(i, j, k) < 0.0)
count += 1.0;
}
}
}
@ -894,4 +949,3 @@ double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
return count;
}

View File

@ -3,9 +3,14 @@
#include "common/Domain.h"
#include "analysis/runAnalysis.h"
double MorphOpen(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction, signed char ErodeLabel, signed char ReplaceLabel);
double MorphDrain(DoubleArray &SignDist, signed char *id, std::shared_ptr<Domain> Dm, double VoidFraction);
double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id, std::shared_ptr<Domain> Dm, double TargetVol, double WallFactor);
double MorphOpen(DoubleArray &SignDist, signed char *id,
std::shared_ptr<Domain> Dm, double VoidFraction,
signed char ErodeLabel, signed char ReplaceLabel);
double MorphDrain(DoubleArray &SignDist, signed char *id,
std::shared_ptr<Domain> Dm, double VoidFraction);
double MorphGrow(DoubleArray &BoundaryDist, DoubleArray &Dist, Array<char> &id,
std::shared_ptr<Domain> Dm, double TargetVol,
double WallFactor);
#ifndef MORPHOLOGY_INC
#define MORPHOLOGY_INC
@ -41,7 +46,8 @@ public:
* @param ErodeLabel label to erode based on morphological operation
* @param NewLabel label to assign based on morphological operation
*/
int GetOverlaps(std::shared_ptr <Domain> Dm, signed char *id, const signed char ErodeLabel, const signed char NewLabel);
int GetOverlaps(std::shared_ptr<Domain> Dm, signed char *id,
const signed char ErodeLabel, const signed char NewLabel);
/*
* data structures to store non-local morphological information
@ -58,27 +64,39 @@ private:
//......................................................................................
int sendCount, recvCount;
//......................................................................................
int sendOffset_x, sendOffset_y, sendOffset_z, sendOffset_X, sendOffset_Y, sendOffset_Z;
int sendOffset_xy, sendOffset_yz, sendOffset_xz, sendOffset_Xy, sendOffset_Yz, sendOffset_xZ;
int sendOffset_xY, sendOffset_yZ, sendOffset_Xz, sendOffset_XY, sendOffset_YZ, sendOffset_XZ;
int sendOffset_x, sendOffset_y, sendOffset_z, sendOffset_X, sendOffset_Y,
sendOffset_Z;
int sendOffset_xy, sendOffset_yz, sendOffset_xz, sendOffset_Xy,
sendOffset_Yz, sendOffset_xZ;
int sendOffset_xY, sendOffset_yZ, sendOffset_Xz, sendOffset_XY,
sendOffset_YZ, sendOffset_XZ;
int sendOffset_xyz, sendOffset_XYZ, sendOffset_xYz, sendOffset_XyZ;
int sendOffset_Xyz, sendOffset_xYZ, sendOffset_xyZ, sendOffset_XYz;
//......................................................................................
int recvOffset_x, recvOffset_y, recvOffset_z, recvOffset_X, recvOffset_Y, recvOffset_Z;
int recvOffset_xy, recvOffset_yz, recvOffset_xz, recvOffset_Xy, recvOffset_Yz, recvOffset_xZ;
int recvOffset_xY, recvOffset_yZ, recvOffset_Xz, recvOffset_XY, recvOffset_YZ, recvOffset_XZ;
int recvOffset_x, recvOffset_y, recvOffset_z, recvOffset_X, recvOffset_Y,
recvOffset_Z;
int recvOffset_xy, recvOffset_yz, recvOffset_xz, recvOffset_Xy,
recvOffset_Yz, recvOffset_xZ;
int recvOffset_xY, recvOffset_yZ, recvOffset_Xz, recvOffset_XY,
recvOffset_YZ, recvOffset_XZ;
int recvOffset_xyz, recvOffset_XYZ, recvOffset_xYz, recvOffset_XyZ;
int recvOffset_Xyz, recvOffset_xYZ, recvOffset_xyZ, recvOffset_XYz;
//......................................................................................
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y, sendCount_Z;
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz, sendCount_xZ;
int sendCount_xY, sendCount_yZ, sendCount_Xz, sendCount_XY, sendCount_YZ, sendCount_XZ;
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y,
sendCount_Z;
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz,
sendCount_xZ;
int sendCount_xY, sendCount_yZ, sendCount_Xz, sendCount_XY, sendCount_YZ,
sendCount_XZ;
int sendCount_xyz, sendCount_XYZ, sendCount_xYz, sendCount_XyZ;
int sendCount_Xyz, sendCount_xYZ, sendCount_xyZ, sendCount_XYz;
//......................................................................................
int recvCount_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y, recvCount_Z;
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz, recvCount_xZ;
int recvCount_xY, recvCount_yZ, recvCount_Xz, recvCount_XY, recvCount_YZ, recvCount_XZ;
int recvCount_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y,
recvCount_Z;
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz,
recvCount_xZ;
int recvCount_xY, recvCount_yZ, recvCount_Xz, recvCount_XY, recvCount_YZ,
recvCount_XZ;
int recvCount_xyz, recvCount_XYZ, recvCount_xYz, recvCount_XyZ;
int recvCount_Xyz, recvCount_xYZ, recvCount_xyZ, recvCount_XYz;
//......................................................................................
@ -87,12 +105,18 @@ private:
//......................................................................................
// Communication buffers
signed char *sendID_x, *sendID_y, *sendID_z, *sendID_X, *sendID_Y, *sendID_Z;
signed char *sendID_xy, *sendID_yz, *sendID_xz, *sendID_Xy, *sendID_Yz, *sendID_xZ;
signed char *sendID_xY, *sendID_yZ, *sendID_Xz, *sendID_XY, *sendID_YZ, *sendID_XZ;
signed char *recvID_x, *recvID_y, *recvID_z, *recvID_X, *recvID_Y, *recvID_Z;
signed char *recvID_xy, *recvID_yz, *recvID_xz, *recvID_Xy, *recvID_Yz, *recvID_xZ;
signed char *recvID_xY, *recvID_yZ, *recvID_Xz, *recvID_XY, *recvID_YZ, *recvID_XZ;
signed char *sendID_x, *sendID_y, *sendID_z, *sendID_X, *sendID_Y,
*sendID_Z;
signed char *sendID_xy, *sendID_yz, *sendID_xz, *sendID_Xy, *sendID_Yz,
*sendID_xZ;
signed char *sendID_xY, *sendID_yZ, *sendID_Xz, *sendID_XY, *sendID_YZ,
*sendID_XZ;
signed char *recvID_x, *recvID_y, *recvID_z, *recvID_X, *recvID_Y,
*recvID_Z;
signed char *recvID_xy, *recvID_yz, *recvID_xz, *recvID_Xy, *recvID_Yz,
*recvID_xZ;
signed char *recvID_xY, *recvID_yZ, *recvID_Xz, *recvID_XY, *recvID_YZ,
*recvID_XZ;
};
#endif

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

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"
// Inline function to read line without a return argument
static inline void fgetl( char * str, int num, FILE * stream )
{
static inline void fgetl(char *str, int num, FILE *stream) {
char *ptr = fgets(str, num, stream);
if ( 0 ) {char *temp = (char *)&ptr; temp++;}
if (0) {
char *temp = (char *)&ptr;
temp++;
}
}
void WriteLocalSolidID(char *FILENAME, char *ID, int N)
{
void WriteLocalSolidID(char *FILENAME, char *ID, int N) {
char value;
ofstream File(FILENAME, ios::binary);
for (int n = 0; n < N; n++) {
@ -64,8 +65,7 @@ void WriteLocalSolidID(char *FILENAME, char *ID, int N)
File.close();
}
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N)
{
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N) {
double value;
ofstream File(FILENAME, ios::binary);
for (int n = 0; n < N; n++) {
@ -75,8 +75,8 @@ void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N)
File.close();
}
void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad)
{
void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy,
double *List_cz, double *List_rad) {
// Read in the full sphere pack
//...... READ IN THE SPHERES...................................
cout << "Reading the packing file..." << endl;
@ -101,14 +101,16 @@ void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *L
count++;
}
cout << "Number of spheres extracted is: " << count << endl;
INSIST( count==nspheres, "Specified number of spheres is probably incorrect!" );
INSIST(count == nspheres,
"Specified number of spheres is probably incorrect!");
// .............................................................
}
void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
void AssignLocalSolidID(char *ID, int nspheres, double *List_cx,
double *List_cy, double *List_cz, double *List_rad,
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz)
{
int iproc, int jproc, int kproc, int nprocx, int nprocy,
int nprocz) {
// Use sphere lists to determine which nodes are in porespace
// Write out binary file for nodes
char value;
@ -163,18 +165,30 @@ void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy
kmin = int((cz - r) / hz) - 1;
kmax = int((cz + r) / hz) + 1;
// Obviously we have to do something at the edges
if (imin<0) imin = 0;
if (imin>Nx) imin = Nx;
if (imax<0) imax = 0;
if (imax>Nx) imax = Nx;
if (jmin<0) jmin = 0;
if (jmin>Ny) jmin = Ny;
if (jmax<0) jmax = 0;
if (jmax>Ny) jmax = Ny;
if (kmin<0) kmin = 0;
if (kmin>Nz) kmin = Nz;
if (kmax<0) kmax = 0;
if (kmax>Nz) kmax = Nz;
if (imin < 0)
imin = 0;
if (imin > Nx)
imin = Nx;
if (imax < 0)
imax = 0;
if (imax > Nx)
imax = Nx;
if (jmin < 0)
jmin = 0;
if (jmin > Ny)
jmin = Ny;
if (jmax < 0)
jmax = 0;
if (jmax > Ny)
jmax = Ny;
if (kmin < 0)
kmin = 0;
if (kmin > Nz)
kmin = Nz;
if (kmax < 0)
kmax = 0;
if (kmax > Nz)
kmax = Nz;
// Loop over the domain for this sphere (may be null)
for (i = imin; i < imax; i++) {
for (j = jmin; j < jmax; j++) {
@ -185,7 +199,9 @@ void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy
z = k * hz;
value = 1;
// if inside sphere, set to zero
if ( (cx-x)*(cx-x)+(cy-y)*(cy-y)+(cz-z)*(cz-z) < r*r){
if ((cx - x) * (cx - x) + (cy - y) * (cy - y) +
(cz - z) * (cz - z) <
r * r) {
value = 0;
}
// get the position in the list
@ -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,
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz)
{
int iproc, int jproc, int kproc, int nprocx, int nprocy,
int nprocz) {
// Use sphere lists to determine which nodes are in porespace
// Write out binary file for nodes
int N = Nx * Ny * Nz; // Domain size, including the halo
@ -253,18 +270,30 @@ void SignedDistance(double *Distance, int nspheres, double *List_cx, double *Lis
kmin = int((cz - 2 * r) / hz);
kmax = int((cz + 2 * r) / hz) + 2;
// Obviously we have to do something at the edges
if (imin<0) imin = 0;
if (imin>Nx) imin = Nx;
if (imax<0) imax = 0;
if (imax>Nx) imax = Nx;
if (jmin<0) jmin = 0;
if (jmin>Ny) jmin = Ny;
if (jmax<0) jmax = 0;
if (jmax>Ny) jmax = Ny;
if (kmin<0) kmin = 0;
if (kmin>Nz) kmin = Nz;
if (kmax<0) kmax = 0;
if (kmax>Nz) kmax = Nz;
if (imin < 0)
imin = 0;
if (imin > Nx)
imin = Nx;
if (imax < 0)
imax = 0;
if (imax > Nx)
imax = Nx;
if (jmin < 0)
jmin = 0;
if (jmin > Ny)
jmin = Ny;
if (jmax < 0)
jmax = 0;
if (jmax > Ny)
jmax = Ny;
if (kmin < 0)
kmin = 0;
if (kmin > Nz)
kmin = Nz;
if (kmax < 0)
kmax = 0;
if (kmax > Nz)
kmax = Nz;
// Loop over the domain for this sphere (may be null)
for (i = imin; i < imax; i++) {
for (j = jmin; j < jmax; j++) {
@ -277,15 +306,18 @@ void SignedDistance(double *Distance, int nspheres, double *List_cx, double *Lis
// get the position in the list
n = k * Nx * Ny + j * Nx + i;
// Compute the distance
distance = sqrt((cx-x)*(cx-x)+(cy-y)*(cy-y)+(cz-z)*(cz-z)) - r;
distance = sqrt((cx - x) * (cx - x) + (cy - y) * (cy - y) +
(cz - z) * (cz - z)) -
r;
// Assign the minimum distance
if (distance < Distance[n]) Distance[n] = distance;
if (distance < Distance[n])
Distance[n] = distance;
}
}
}
}
// Map the distance to lattice units
for (n=0; n<N; n++) Distance[n] = Distance[n]/hx;
for (n = 0; n < N; n++)
Distance[n] = Distance[n] / hx;
}

View File

@ -40,14 +40,19 @@ void WriteLocalSolidID(char *FILENAME, char *ID, int N);
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N);
void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad);
void ReadSpherePacking(int nspheres, double *List_cx, double *List_cy,
double *List_cz, double *List_rad);
void AssignLocalSolidID(char *ID, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
void AssignLocalSolidID(char *ID, int nspheres, double *List_cx,
double *List_cy, double *List_cz, double *List_rad,
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz);
int iproc, int jproc, int kproc, int nprocx, int nprocy,
int nprocz);
void SignedDistance(double *Distance, int nspheres, double *List_cx, double *List_cy, double *List_cz, double *List_rad,
void SignedDistance(double *Distance, int nspheres, double *List_cx,
double *List_cy, double *List_cz, double *List_rad,
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
int iproc, int jproc, int kproc, int nprocx, int nprocy, int nprocz);
int iproc, int jproc, int kproc, int nprocx, int nprocy,
int nprocz);
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,14 +23,20 @@ public:
// Set up for D3Q19 distributions -- all 27 neighbors are needed
//......................................................................................
// Buffers to store data sent and recieved by this MPI process
double *sendbuf_x, *sendbuf_y, *sendbuf_z, *sendbuf_X, *sendbuf_Y, *sendbuf_Z;
double *sendbuf_xy, *sendbuf_yz, *sendbuf_xz, *sendbuf_Xy, *sendbuf_Yz, *sendbuf_xZ;
double *sendbuf_xY, *sendbuf_yZ, *sendbuf_Xz, *sendbuf_XY, *sendbuf_YZ, *sendbuf_XZ;
double *sendbuf_x, *sendbuf_y, *sendbuf_z, *sendbuf_X, *sendbuf_Y,
*sendbuf_Z;
double *sendbuf_xy, *sendbuf_yz, *sendbuf_xz, *sendbuf_Xy, *sendbuf_Yz,
*sendbuf_xZ;
double *sendbuf_xY, *sendbuf_yZ, *sendbuf_Xz, *sendbuf_XY, *sendbuf_YZ,
*sendbuf_XZ;
double *sendbuf_xyz, *sendbuf_Xyz, *sendbuf_xYz, *sendbuf_XYz;
double *sendbuf_xyZ, *sendbuf_XyZ, *sendbuf_xYZ, *sendbuf_XYZ;
double *recvbuf_x, *recvbuf_y, *recvbuf_z, *recvbuf_X, *recvbuf_Y, *recvbuf_Z;
double *recvbuf_xy, *recvbuf_yz, *recvbuf_xz, *recvbuf_Xy, *recvbuf_Yz, *recvbuf_xZ;
double *recvbuf_xY, *recvbuf_yZ, *recvbuf_Xz, *recvbuf_XY, *recvbuf_YZ, *recvbuf_XZ;
double *recvbuf_x, *recvbuf_y, *recvbuf_z, *recvbuf_X, *recvbuf_Y,
*recvbuf_Z;
double *recvbuf_xy, *recvbuf_yz, *recvbuf_xz, *recvbuf_Xy, *recvbuf_Yz,
*recvbuf_xZ;
double *recvbuf_xY, *recvbuf_yZ, *recvbuf_Xz, *recvbuf_XY, *recvbuf_YZ,
*recvbuf_XZ;
double *recvbuf_xyz, *recvbuf_Xyz, *recvbuf_xYz, *recvbuf_XYz;
double *recvbuf_xyZ, *recvbuf_XyZ, *recvbuf_xYZ, *recvbuf_XYZ;
//......................................................................................
@ -45,7 +51,8 @@ public:
void PrintDebug();
private:
bool Lock; // use Lock to make sure only one call at a time to protect data in transit
bool
Lock; // use Lock to make sure only one call at a time to protect data in transit
// only one set of Send requests can be active at any time (per instance)
int i, j, k, n;
int iproc, jproc, kproc;
@ -68,33 +75,46 @@ private:
int rank_xyZ, rank_XyZ, rank_xYZ, rank_XYZ;
//......................................................................................
//......................................................................................
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y, sendCount_Z;
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz, sendCount_xZ;
int sendCount_xY, sendCount_yZ, sendCount_Xz, sendCount_XY, sendCount_YZ, sendCount_XZ;
int sendCount_x, sendCount_y, sendCount_z, sendCount_X, sendCount_Y,
sendCount_Z;
int sendCount_xy, sendCount_yz, sendCount_xz, sendCount_Xy, sendCount_Yz,
sendCount_xZ;
int sendCount_xY, sendCount_yZ, sendCount_Xz, sendCount_XY, sendCount_YZ,
sendCount_XZ;
int sendCount_xyz, sendCount_Xyz, sendCount_xYz, sendCount_XYz;
int sendCount_xyZ, sendCount_XyZ, sendCount_xYZ, sendCount_XYZ;
//......................................................................................
int recvCount_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y, recvCount_Z;
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz, recvCount_xZ;
int recvCount_xY, recvCount_yZ, recvCount_Xz, recvCount_XY, recvCount_YZ, recvCount_XZ;
int recvCount_x, recvCount_y, recvCount_z, recvCount_X, recvCount_Y,
recvCount_Z;
int recvCount_xy, recvCount_yz, recvCount_xz, recvCount_Xy, recvCount_Yz,
recvCount_xZ;
int recvCount_xY, recvCount_yZ, recvCount_Xz, recvCount_XY, recvCount_YZ,
recvCount_XZ;
int recvCount_xyz, recvCount_Xyz, recvCount_xYz, recvCount_XYz;
int recvCount_xyZ, recvCount_XyZ, recvCount_xYZ, recvCount_XYZ;
//......................................................................................
// Send buffers that reside on the compute device
int *dvcSendList_x, *dvcSendList_y, *dvcSendList_z, *dvcSendList_X, *dvcSendList_Y, *dvcSendList_Z;
int *dvcSendList_xy, *dvcSendList_yz, *dvcSendList_xz, *dvcSendList_Xy, *dvcSendList_Yz, *dvcSendList_xZ;
int *dvcSendList_xY, *dvcSendList_yZ, *dvcSendList_Xz, *dvcSendList_XY, *dvcSendList_YZ, *dvcSendList_XZ;
int *dvcSendList_x, *dvcSendList_y, *dvcSendList_z, *dvcSendList_X,
*dvcSendList_Y, *dvcSendList_Z;
int *dvcSendList_xy, *dvcSendList_yz, *dvcSendList_xz, *dvcSendList_Xy,
*dvcSendList_Yz, *dvcSendList_xZ;
int *dvcSendList_xY, *dvcSendList_yZ, *dvcSendList_Xz, *dvcSendList_XY,
*dvcSendList_YZ, *dvcSendList_XZ;
int *dvcSendList_xyz, *dvcSendList_Xyz, *dvcSendList_xYz, *dvcSendList_XYz;
int *dvcSendList_xyZ, *dvcSendList_XyZ, *dvcSendList_xYZ, *dvcSendList_XYZ;
// Recieve buffers that reside on the compute device
int *dvcRecvList_x, *dvcRecvList_y, *dvcRecvList_z, *dvcRecvList_X, *dvcRecvList_Y, *dvcRecvList_Z;
int *dvcRecvList_xy, *dvcRecvList_yz, *dvcRecvList_xz, *dvcRecvList_Xy, *dvcRecvList_Yz, *dvcRecvList_xZ;
int *dvcRecvList_xY, *dvcRecvList_yZ, *dvcRecvList_Xz, *dvcRecvList_XY, *dvcRecvList_YZ, *dvcRecvList_XZ;
int *dvcRecvList_x, *dvcRecvList_y, *dvcRecvList_z, *dvcRecvList_X,
*dvcRecvList_Y, *dvcRecvList_Z;
int *dvcRecvList_xy, *dvcRecvList_yz, *dvcRecvList_xz, *dvcRecvList_Xy,
*dvcRecvList_Yz, *dvcRecvList_xZ;
int *dvcRecvList_xY, *dvcRecvList_yZ, *dvcRecvList_Xz, *dvcRecvList_XY,
*dvcRecvList_YZ, *dvcRecvList_XZ;
int *dvcRecvList_xyz, *dvcRecvList_Xyz, *dvcRecvList_xYz, *dvcRecvList_XYz;
int *dvcRecvList_xyZ, *dvcRecvList_XyZ, *dvcRecvList_xYZ, *dvcRecvList_XYZ;
//......................................................................................
inline int getHaloBlock(int imin, int imax, int jmin, int jmax, int kmin, int kmax, int *& dvcList){
inline int getHaloBlock(int imin, int imax, int jmin, int jmax, int kmin,
int kmax, int *&dvcList) {
int count = 0;
int *List;
List = new int[(imax - imin) * (jmax - jmin) * (kmax - kmin)];
@ -106,10 +126,10 @@ private:
}
}
size_t numbytes = count * sizeof(int);
ScaLBL_AllocateZeroCopy((void **) &dvcList, numbytes); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **)&dvcList,
numbytes); // Allocate device memory
ScaLBL_CopyToZeroCopy(dvcList, List, numbytes);
return count;
}
};
#endif

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@
*/
#include <stdio.h>
extern "C" void ScaLBL_D3Q19_Pack(int q, int *list, int start, int count, double *sendbuf, double *dist, int N){
extern "C" void ScaLBL_D3Q19_Pack(int q, int *list, int start, int count,
double *sendbuf, double *dist, int N) {
//....................................................................................
// Pack distribution q into the send buffer for the listed lattice sites
// dist may be even or odd distributions stored by stream layout
@ -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
n = list[start + idx];
// unpack the distribution to the proper location
if (!(n<0)) dist[q*N+n] = recvbuf[start+idx];
if (!(n < 0))
dist[q * N + n] = recvbuf[start + idx];
//dist[q*N+n] = recvbuf[start+idx];
}
}
extern "C" void ScaLBL_D3Q19_AA_Init(double *f_even, double *f_odd, int Np)
{
extern "C" void ScaLBL_D3Q19_AA_Init(double *f_even, double *f_odd, int Np) {
int n;
for (n = 0; n < Np; n++) {
f_even[n] = 0.3333333333333333;
@ -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_odd[8 * Np + n] = 0.0277777777777778; //double(100*n)+17.f;
f_even[9 * Np + n] = 0.0277777777777778; //double(100*n)+18.f;
}
}
extern "C" void ScaLBL_D3Q19_Init(double *dist, int Np)
{
extern "C" void ScaLBL_D3Q19_Init(double *dist, int Np) {
int n;
for (n = 0; n < Np; n++) {
dist[n] = 0.3333333333333333;
@ -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;
// distributions
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)
//........................................................................
nn = n + 1; // neighbor index (pull convention)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
if (!(i + 1 < Nx))
nn -= Nx; // periodic BC along the x-boundary
//if (i+1<Nx){
f2 = disteven[N + nn]; // pull neighbor for distribution 2
if (f2 > 0) {
@ -145,7 +144,8 @@ extern "C" void ScaLBL_D3Q19_Swap(char *ID, double *disteven, double *distodd, i
//}
//........................................................................
nn = n + Nx; // neighbor index (pull convention)
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
if (!(j + 1 < Ny))
nn -= Nx * Ny; // Perioidic BC along the y-boundary
//if (j+1<Ny){
f4 = disteven[2 * N + nn]; // pull neighbor for distribution 4
if (f4 > 0) {
@ -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)
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary
if (!(k + 1 < Nz))
nn -= Nx * Ny * Nz; // Perioidic BC along the z-boundary
//if (k+1<Nz){
f6 = disteven[3 * N + nn]; // pull neighbor for distribution 6
if (f6 > 0) {
@ -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)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
if (!(i + 1 < Nx))
nn -= Nx; // periodic BC along the x-boundary
if (!(j + 1 < Ny))
nn -= Nx * Ny; // Perioidic BC along the y-boundary
//if ((i+1<Nx) && (j+1<Ny)){
f8 = disteven[4 * N + nn]; // pull neighbor for distribution 8
if (f8 > 0) {
@ -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)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
if (j-1<0) nn += Nx*Ny; // Perioidic BC along the y-boundary
if (!(i + 1 < Nx))
nn -= Nx; // periodic BC along the x-boundary
if (j - 1 < 0)
nn += Nx * Ny; // Perioidic BC along the y-boundary
//if (!(i-1<0) && (j+1<Ny)){
f10 = disteven[5 * N + nn]; // pull neighbor for distribution 9
if (f10 > 0) {
@ -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)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary
if (!(i + 1 < Nx))
nn -= Nx; // periodic BC along the x-boundary
if (!(k + 1 < Nz))
nn -= Nx * Ny * Nz; // Perioidic BC along the z-boundary
//if ( !(i-1<0) && !(k-1<0)){
f12 = disteven[6 * N + nn]; // pull distribution 11
if (f12 > 0) {
@ -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)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
if (k-1<0) nn += Nx*Ny*Nz; // Perioidic BC along the z-boundary
if (!(i + 1 < Nx))
nn -= Nx; // periodic BC along the x-boundary
if (k - 1 < 0)
nn += Nx * Ny * Nz; // Perioidic BC along the z-boundary
//if (!(i-1<0) && (k+1<Nz)){
f14 = disteven[7 * N + nn]; // pull neighbor for distribution 13
if (f14 > 0) {
@ -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)
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary
if (!(j + 1 < Ny))
nn -= Nx * Ny; // Perioidic BC along the y-boundary
if (!(k + 1 < Nz))
nn -= Nx * Ny * Nz; // Perioidic BC along the z-boundary
//if (!(j-1<0) && !(k-1<0)){
f16 = disteven[8 * N + nn]; // pull neighbor for distribution 15
if (f16 > 0) {
@ -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)
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
if (k-1<0) nn += Nx*Ny*Nz; // Perioidic BC along the z-boundary
if (!(j + 1 < Ny))
nn -= Nx * Ny; // Perioidic BC along the y-boundary
if (k - 1 < 0)
nn += Nx * Ny * Nz; // Perioidic BC along the z-boundary
//if (!(j-1<0) && (k+1<Nz)){
f18 = disteven[9 * N + nn]; // pull neighbor for distribution 17
if (f18 > 0) {
@ -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;
double f1, f2;
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, double flux,
int Nx, int Ny, int Nz){
extern "C" double ScaLBL_D3Q19_Flux_BC_z(double *disteven, double *distodd,
double flux, int Nx, int Ny, int Nz) {
// Note that this routine assumes the distributions are stored "opposite"
// odd distributions in disteven and even distributions in distodd.
int n, N;
@ -295,15 +306,16 @@ extern "C" double ScaLBL_D3Q19_Flux_BC_z(double *disteven, double *distodd, doub
// Determine the outlet flow velocity
//sum += 1.0 - (f0+f4+f3+f2+f1+f8+f7+f9+ f10 + 2*(f5+ f15+f18+f11+f14))/din;
//sum += (f0+f4+f3+f2+f1+f8+f7+f9+ f10 + 2*(f5+f15+f18+f11+f14));
sum += (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
sum += (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
2 * (f6 + f12 + f13 + f16 + f17));
}
din = sum / (A * (1.0 - flux));
return din;
}
extern "C" double ScaLBL_D3Q19_AAodd_Flux_BC_z(int *d_neighborList, int *list, double *dist, double flux,
double area, int count, int Np)
{
extern "C" double ScaLBL_D3Q19_AAodd_Flux_BC_z(int *d_neighborList, int *list,
double *dist, double flux,
double area, int count, int Np) {
int idx, n;
int nread;
@ -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];
double f16 = dist[nread];
sum += factor*(f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
sum += factor * (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
2 * (f6 + f12 + f13 + f16 + f17));
}
return sum;
}
extern "C" double ScaLBL_D3Q19_AAeven_Flux_BC_z(int *list, double *dist, double flux, double area,
int count, int Np)
{
extern "C" double ScaLBL_D3Q19_AAeven_Flux_BC_z(int *list, double *dist,
double flux, double area,
int count, int Np) {
int idx, n;
// distributions
double factor = 1.f / (area);
@ -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 f16 = dist[15 * Np + n];
double f17 = dist[18 * Np + n];
sum += factor*(f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
sum += factor * (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
2 * (f6 + f12 + f13 + f16 + f17));
}
return sum;
}
extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd, double flux,
int Nx, int Ny, int Nz, int outlet){
extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd,
double flux, int Nx, int Ny, int Nz,
int outlet) {
// Note that this routine assumes the distributions are stored "opposite"
// odd distributions in disteven and even distributions in distodd.
int n, N;
@ -430,14 +444,15 @@ extern "C" double ScaLBL_D3Q19_Flux_BC_Z(double *disteven, double *distodd, doub
//double f16 = disteven[8*N+n];
double f18 = disteven[9 * N + n];
sum += (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f5+f11+f14+f15+f18));
sum += (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
2 * (f5 + f11 + f14 + f15 + f18));
}
dout = sum / (A * (1.0 + flux));
return dout;
}
extern "C" void ScaLBL_D3Q19_Reflection_BC_z(int *list, double *dist, int count, int Np){
extern "C" void ScaLBL_D3Q19_Reflection_BC_z(int *list, double *dist, int count,
int Np) {
for (int idx = 0; idx < count; idx++) {
int n = list[idx];
@ -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++) {
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
double ux, uy, uz, Cyz, Cxz;
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
//ux = (f1-f2+f7-f8+f9-f10+f11-f12+f13-f14);
//uy = (f3-f4+f7-f8-f9+f10+f15-f16+f17-f18);
uz = din - (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
uz = din - (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
2 * (f6 + f12 + f13 + f16 + f17));
Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
@ -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
double ux, uy, uz, Cyz, Cxz;
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
//ux = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14;
//uy = f3-f4+f7-f8-f9+f10+f15-f16+f17-f18;
uz = -dout + (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f5+f11+f14+f15+f18));
uz = -dout + (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
2 * (f5 + f11 + f14 + f15 + f18));
Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
@ -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 nr5, nr11, nr14, nr15, nr18;
// distributions
@ -627,7 +648,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_Pressure_BC_z(int *d_neighborList, int *list,
// Determine the inlet flow velocity
//ux = (f1-f2+f7-f8+f9-f10+f11-f12+f13-f14);
//uy = (f3-f4+f7-f8-f9+f10+f15-f16+f17-f18);
uz = din - (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f6+f12+f13+f16+f17));
uz = din - (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
2 * (f6 + f12 + f13 + f16 + f17));
Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
@ -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 nr6, nr12, nr13, nr16, nr17;
// 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];
double f15 = dist[nread];
nread = d_neighborList[n + Np];
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
//ux = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14;
//uy = f3-f4+f7-f8-f9+f10+f15-f16+f17-f18;
uz = -dout + (f0+f1+f2+f3+f4+f7+f8+f9+f10 + 2*(f5+f11+f14+f15+f18));
uz = -dout + (f0 + f1 + f2 + f3 + f4 + f7 + f8 + f9 + f10 +
2 * (f5 + f11 + f14 + f15 + f18));
Cxz = 0.5 * (f1 + f7 + f9 - f2 - f10 - f8) - 0.3333333333333333 * ux;
Cyz = 0.5 * (f3 + f7 + f10 - f4 - f9 - f8) - 0.3333333333333333 * uy;
@ -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,
int Nx, int Ny, int Nz)
{
extern "C" void ScaLBL_D3Q19_Velocity_BC_z(double *disteven, double *distodd,
double uz, int Nx, int Ny, int Nz) {
int n, N;
// distributions
double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
@ -774,12 +796,16 @@ extern "C" void ScaLBL_D3Q19_Velocity_BC_z(double *disteven, double *distodd, do
// Determine the outlet flow velocity
// uz = 1.0 - (f0+f4+f3+f2+f1+f8+f7+f9+f10 +
// 2*(f5+f15+f18+f11+f14))/din;
din = (f0+f4+f3+f2+f1+f8+f7+f9+f10+2*(f5+f15+f18+f11+f14))/(1.0-uz);
din = (f0 + f4 + f3 + f2 + f1 + f8 + f7 + f9 + f10 +
2 * (f5 + f15 + f18 + f11 + f14)) /
(1.0 - uz);
// Set the unknown distributions:
f6 = f5 + 0.3333333333333333 * din * uz;
f16 = f15 + 0.1666666666666667 * din * uz;
f17 = f16 + f4 - f3 - f15 + f18 + f8 - f7 + f9 - f10;
f12= (din*uz+f5+ f15+f18+f11+f14-f6-f16-f17-f2+f1-f14+f11-f8+f7+f9-f10)*0.5;
f12 = (din * uz + f5 + f15 + f18 + f11 + f14 - f6 - f16 - f17 - f2 +
f1 - f14 + f11 - f8 + f7 + f9 - f10) *
0.5;
f13 = din * uz + f5 + f15 + f18 + f11 + f14 - f6 - f16 - f17 - f12;
//........Store in "opposite" memory location..........
@ -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,
int Nx, int Ny, int Nz, int outlet)
{
extern "C" void ScaLBL_D3Q19_Velocity_BC_Z(double *disteven, double *distodd,
double uz, int Nx, int Ny, int Nz,
int outlet) {
int n, N;
// distributions
double f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
@ -829,11 +855,15 @@ extern "C" void ScaLBL_D3Q19_Velocity_BC_Z(double *disteven, double *distodd, do
f16 = disteven[8 * N + n];
f18 = disteven[9 * N + n];
//uz = -1.0 + (f0+f4+f3+f2+f1+f8+f7+f9+f10 + 2*(f6+f16+f17+f12+f13))/dout;
dout = (f0+f4+f3+f2+f1+f8+f7+f9+f10 + 2*(f6+f16+f17+f12+f13))/(1.0+uz);
dout = (f0 + f4 + f3 + f2 + f1 + f8 + f7 + f9 + f10 +
2 * (f6 + f16 + f17 + f12 + f13)) /
(1.0 + uz);
f5 = f6 - 0.33333333333333338 * dout * uz;
f15 = f16 - 0.16666666666666678 * dout * uz;
f18 = f15 - f4 + f3 - f16 + f17 - f8 + f7 - f9 + f10;
f11 = (-dout*uz+f6+ f16+f17+f12+f13-f5-f15-f18+f2-f1-f13+f12+f8-f7-f9+f10)*0.5;
f11 = (-dout * uz + f6 + f16 + f17 + f12 + f13 - f5 - f15 - f18 + f2 -
f1 - f13 + f12 + f8 - f7 - f9 + f10) *
0.5;
f14 = -dout * uz + f6 + f16 + f17 + f12 + f13 - f5 - f15 - f18 - f11;
//........Store in "opposite" memory location..........
distodd[2 * N + n] = f5;
@ -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 = Np;
// 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++) {
//........................................................................
// 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 f17 = dist[17 * N + n];
//.................Compute the velocity...................................
Pressure[n] = 0.3333333333333333*(f0+f2+f1+f4+f3+f6+f5+f8+f7+f10+
f9+f12+f11+f14+f13+f16+f15+f18+f17);
Pressure[n] = 0.3333333333333333 *
(f0 + f2 + f1 + f4 + f3 + f6 + f5 + f8 + f7 + f10 + f9 +
f12 + f11 + f14 + f13 + f16 + f15 + f18 + f17);
}
}
extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int Np, double rlx_setA, double rlx_setB, double Fx,
double Fy, double Fz)
{
extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish,
int Np, double rlx_setA,
double rlx_setB, double Fx, double Fy,
double Fz) {
// conserved momemnts
double rho, jx, jy, jz;
// non-conserved moments
@ -1213,8 +1243,6 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
m17 -= fq;
m18 -= fq;
//........................................................................
// READ THE DISTRIBUTIONS
// (read from opposite array due to previous swap operation)
@ -1222,13 +1250,19 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
//..............incorporate external force................................................
//..............carry out relaxation process...............................................
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1);
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2);
m1 = m1 +
rlx_setA *
((19 * (jx * jx + jy * jy + jz * jz) / rho - 11 * rho) - m1);
m2 = m2 +
rlx_setA *
((3 * rho - 5.5 * (jx * jx + jy * jy + jz * jz) / rho) - m2);
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho) - m9);
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
m10 =
m10 +
rlx_setA * (-0.5 * ((2 * jx * jx - jy * jy - jz * jz) / rho) - m10);
m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12);
m13 = m13 + rlx_setA * ((jx * jy / rho) - m13);
@ -1245,114 +1279,124 @@ extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int
dist[n] = fq;
// q = 1
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10) + 0.16666666*Fx;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jx - m4) +
mrt_V6 * (m9 - m10) + 0.16666666 * Fx;
dist[1 * Np + n] = fq;
// q=2
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10) - 0.16666666*Fx;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m4 - jx) +
mrt_V6 * (m9 - m10) - 0.16666666 * Fx;
dist[2 * Np + n] = fq;
// q = 3
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) + 0.16666666*Fy;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jy - m6) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) + 0.16666666 * Fy;
dist[3 * Np + n] = fq;
// q = 4
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) - 0.16666666*Fy;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m6 - jy) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) - 0.16666666 * Fy;
dist[4 * Np + n] = fq;
// q = 5
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) + 0.16666666*Fz;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jz - m8) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) + 0.16666666 * Fz;
dist[5 * Np + n] = fq;
// q = 6
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) - 0.16666666*Fz;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m8 - jz) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) - 0.16666666 * Fz;
dist[6 * Np + n] = fq;
// q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(Fx+Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (Fx + Fy);
dist[7 * Np + n] = fq;
// q = 8
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m17 - m16) -
0.08333333333 * (Fx + Fy);
dist[8 * Np + n] = fq;
// q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(Fx-Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
0.025 * (m4 - m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (Fx - Fy);
dist[9 * Np + n] = fq;
// q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(Fx-Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
0.025 * (m6 - m4) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (Fx - Fy);
dist[10 * Np + n] = fq;
// q = 11
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
0.08333333333 * (Fx + Fz);
dist[11 * Np + n] = fq;
// q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m16-m18) - 0.08333333333*(Fx+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (Fx + Fz);
dist[12 * Np + n] = fq;
// q = 13
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
0.08333333333 * (Fx - Fz);
dist[13 * Np + n] = fq;
// q= 14
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
0.08333333333 * (Fx - Fz);
dist[14 * Np + n] = fq;
// q = 15
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
dist[15 * Np + n] = fq;
// q = 16
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
dist[16 * Np + n] = fq;
// q = 17
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8)
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
dist[17 * Np + n] = fq;
// q = 18
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6)
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
dist[18 * Np + n] = fq;
//........................................................................
}
}
extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int start, int finish, int Np, double rlx_setA, double rlx_setB, double Fx,
double Fy, double Fz)
{
extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist,
int start, int finish, int Np,
double rlx_setA, double rlx_setB,
double Fx, double Fy, double Fz) {
// conserved momemnts
double rho, jx, jy, jz;
// non-conserved moments
@ -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_V12 = 0.04166666666666666;
int nread;
for (int n = start; n < finish; n++) {
// q=0
@ -1392,7 +1435,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
m10 = -4.0 * fq;
// f2 = dist[10*Np+n];
nread = neighborList[n+Np]; // neighbor 1 ( < 10Np => even part of dist)
nread =
neighborList[n + Np]; // neighbor 1 ( < 10Np => even part of dist)
fq = dist[nread]; // reading the f2 data into register fq
//fq = dist[Np+n];
rho += fq;
@ -1445,7 +1489,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
m11 -= fq;
m12 += 2.0 * fq;
// q = 6
nread = neighborList[n + 5 * Np];
fq = dist[nread];
@ -1682,13 +1725,19 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
//..............incorporate external force................................................
//..............carry out relaxation process...............................................
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1);
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2);
m1 = m1 +
rlx_setA *
((19 * (jx * jx + jy * jy + jz * jz) / rho - 11 * rho) - m1);
m2 = m2 +
rlx_setA *
((3 * rho - 5.5 * (jx * jx + jy * jy + jz * jz) / rho) - m2);
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / rho) - m9);
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
m10 =
m10 +
rlx_setA * (-0.5 * ((2 * jx * jx - jy * jy - jz * jz) / rho) - m10);
m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12);
m13 = m13 + rlx_setA * ((jx * jy / rho) - m13);
@ -1705,128 +1754,136 @@ extern "C" void ScaLBL_D3Q19_AAodd_MRT(int *neighborList, double *dist, int star
dist[n] = fq;
// q = 1
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10)+0.16666666*Fx;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jx - m4) +
mrt_V6 * (m9 - m10) + 0.16666666 * Fx;
nread = neighborList[n + Np];
dist[nread] = fq;
// q=2
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10) - 0.16666666*Fx;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m4 - jx) +
mrt_V6 * (m9 - m10) - 0.16666666 * Fx;
nread = neighborList[n];
dist[nread] = fq;
// q = 3
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) + 0.16666666*Fy;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jy - m6) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) + 0.16666666 * Fy;
nread = neighborList[n + 3 * Np];
dist[nread] = fq;
// q = 4
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) - 0.16666666*Fy;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m6 - jy) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) - 0.16666666 * Fy;
nread = neighborList[n + 2 * Np];
dist[nread] = fq;
// q = 5
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) + 0.16666666*Fz;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jz - m8) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) + 0.16666666 * Fz;
nread = neighborList[n + 5 * Np];
dist[nread] = fq;
// q = 6
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) - 0.16666666*Fz;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m8 - jz) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) - 0.16666666 * Fz;
nread = neighborList[n + 4 * Np];
dist[nread] = fq;
// q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(Fx+Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (Fx + Fy);
nread = neighborList[n + 7 * Np];
dist[nread] = fq;
// q = 8
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m17 - m16) -
0.08333333333 * (Fx + Fy);
nread = neighborList[n + 6 * Np];
dist[nread] = fq;
// q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(Fx-Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
0.025 * (m4 - m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (Fx - Fy);
nread = neighborList[n + 9 * Np];
dist[nread] = fq;
// q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(Fx-Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
0.025 * (m6 - m4) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (Fx - Fy);
nread = neighborList[n + 8 * Np];
dist[nread] = fq;
// q = 11
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
0.08333333333 * (Fx + Fz);
nread = neighborList[n + 11 * Np];
dist[nread] = fq;
// q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m16-m18) - 0.08333333333*(Fx+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (Fx + Fz);
nread = neighborList[n + 10 * Np];
dist[nread] = fq;
// q = 13
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
0.08333333333 * (Fx - Fz);
nread = neighborList[n + 13 * Np];
dist[nread] = fq;
// q= 14
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
0.08333333333 * (Fx - Fz);
nread = neighborList[n + 12 * Np];
dist[nread] = fq;
// q = 15
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
nread = neighborList[n + 15 * Np];
dist[nread] = fq;
// q = 16
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
nread = neighborList[n + 14 * Np];
dist[nread] = fq;
// q = 17
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8)
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
nread = neighborList[n + 17 * Np];
dist[nread] = fq;
// q = 18
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6)
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
nread = neighborList[n + 16 * Np];
dist[nread] = fq;
}
}
extern "C" void ScaLBL_D3Q19_AAeven_Compact(char * ID, double *dist, int Np)
{
extern "C" void ScaLBL_D3Q19_AAeven_Compact(char *ID, double *dist, int Np) {
for (int n = 0; n < Np; n++) {
@ -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;
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];
double f18 = dist[nread];
nread = neighborList[n + Np];
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];
double f17 = dist[nread];
nread = neighborList[n];
dist[nread] = f1;
@ -1976,7 +2031,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_Compact(char * ID, int *neighborList, double
nread = neighborList[n + 16 * Np];
dist[nread] = f17;
nread = neighborList[n + Np];
dist[nread] = f2;

View File

@ -16,7 +16,8 @@
*/
// CPU Functions for D3Q7 Lattice Boltzmann Methods
extern "C" void ScaLBL_Scalar_Pack(int *list, int count, double *sendbuf, double *Data, int N){
extern "C" void ScaLBL_Scalar_Pack(int *list, int count, double *sendbuf,
double *Data, int N) {
//....................................................................................
// Pack distribution q into the send buffer for the listed lattice sites
// dist may be even or odd distributions stored by stream layout
@ -27,7 +28,8 @@ extern "C" void ScaLBL_Scalar_Pack(int *list, int count, double *sendbuf, double
sendbuf[idx] = Data[n];
}
}
extern "C" void ScaLBL_Scalar_Unpack(int *list, int count, double *recvbuf, double *Data, int N){
extern "C" void ScaLBL_Scalar_Unpack(int *list, int count, double *recvbuf,
double *Data, int N) {
//....................................................................................
// Pack distribution q into the send buffer for the listed lattice sites
// dist may be even or odd distributions stored by stream layout
@ -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
n = list[idx];
// unpack the distribution to the proper location
if (!(n<0)) dist[q*N+n] = recvbuf[start+idx];
if (!(n < 0))
dist[q * N + n] = recvbuf[start + idx];
//dist[q*N+n] = recvbuf[start+idx];
}
}
extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf, int number, double *Data, int N){
extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf,
int number, double *Data, int N) {
//....................................................................................
// Pack distribution into the send buffer for the listed lattice sites
//....................................................................................
@ -68,13 +70,14 @@ extern "C" void ScaLBL_PackDenD3Q7(int *list, int count, double *sendbuf, int nu
for (component = 0; component < number; component++) {
n = list[idx];
sendbuf[idx * number + component] = Data[number * n + component];
Data[number*n+component] = 0.0; // Set the data value to zero once it's in the buffer!
Data[number * n + component] =
0.0; // Set the data value to zero once it's in the buffer!
}
}
}
extern "C" void ScaLBL_UnpackDenD3Q7(int *list, int count, double *recvbuf, int number, double *Data, int N){
extern "C" void ScaLBL_UnpackDenD3Q7(int *list, int count, double *recvbuf,
int number, double *Data, int N) {
//....................................................................................
// Unack distribution from the recv buffer
// Sum to the existing density value
@ -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;
for (int idx = 0; idx < count; 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;
for (int idx = 0; idx < count; 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;
}
}
extern "C" void ScaLBL_D3Q7_Init(char *ID, double *f_even, double *f_odd, double *Den, int Nx, int Ny, int Nz)
{
extern "C" void ScaLBL_D3Q7_Init(char *ID, double *f_even, double *f_odd,
double *Den, int Nx, int Ny, int Nz) {
int n, N;
N = Nx * Ny * Nz;
double value;
@ -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_odd[2 * N + n] = 0.1111111111111111 * value; //double(100*n)+5.f;
f_even[3 * N + n] = 0.1111111111111111 * value; //double(100*n)+6.f;
}
else{
} else {
for (int q = 0; q < 3; q++) {
f_even[q * N + n] = -1.0;
f_odd[q * N + n] = -1.0;
@ -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;
// distributions
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)
//........................................................................
nn = n + 1; // neighbor index (pull convention)
if (!(i+1<Nx)) nn -= Nx; // periodic BC along the x-boundary
if (!(i + 1 < Nx))
nn -= Nx; // periodic BC along the x-boundary
//if (i+1<Nx){
f2 = disteven[N + nn]; // pull neighbor for distribution 2
if (!(f2 < 0.0)) {
@ -171,7 +176,8 @@ extern "C" void ScaLBL_D3Q7_Swap(char *ID, double *disteven, double *distodd, in
//}
//........................................................................
nn = n + Nx; // neighbor index (pull convention)
if (!(j+1<Ny)) nn -= Nx*Ny; // Perioidic BC along the y-boundary
if (!(j + 1 < Ny))
nn -= Nx * Ny; // Perioidic BC along the y-boundary
//if (j+1<Ny){
f4 = disteven[2 * N + nn]; // pull neighbor for distribution 4
if (!(f4 < 0.0)) {
@ -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)
if (!(k+1<Nz)) nn -= Nx*Ny*Nz; // Perioidic BC along the z-boundary
if (!(k + 1 < Nz))
nn -= Nx * Ny * Nz; // Perioidic BC along the z-boundary
//if (k+1<Nz){
f6 = disteven[3 * N + nn]; // pull neighbor for distribution 6
if (!(f6 < 0.0)) {
@ -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,
int Nx, int Ny, int Nz)
{
extern "C" void ScaLBL_D3Q7_Density(char *ID, double *disteven, double *distodd,
double *Den, int Nx, int Ny, int Nz) {
char id;
int n;
double f0, f1, f2, f3, f4, f5, f6;

View File

@ -1,7 +1,9 @@
// CPU Functions for D3Q7 Lattice Boltzmann Methods
// Boundary Conditions
extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist,double *BoundaryValue,int *BounceBackDist_list,int *BounceBackSolid_list,int N){
extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist, double *BoundaryValue,
int *BounceBackDist_list,
int *BounceBackSolid_list, int N) {
int idx;
int iq, ib;
@ -11,12 +13,15 @@ extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist,double *BoundaryValue,i
ib = BounceBackSolid_list[idx];
value_b = BoundaryValue[ib]; //get boundary value from a solid site
value_q = dist[iq];
dist[iq] = -1.0*value_q + value_b*0.25;//NOTE 0.25 is the speed of sound for D3Q7 lattice
dist[iq] =
-1.0 * value_q +
value_b * 0.25; //NOTE 0.25 is the speed of sound for D3Q7 lattice
}
}
extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist,double *BoundaryValue,int *BounceBackDist_list,int *BounceBackSolid_list,int N){
extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist, double *BoundaryValue,
int *BounceBackDist_list,
int *BounceBackSolid_list, int N) {
int idx;
int iq, ib;
@ -30,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,
double epsilon_LB, double tau, double rho0,double den_scale, double h, double time_conv,
int *BounceBackDist_list, int *BounceBackSolid_list, int *FluidBoundary_list,
double *lattice_weight, float *lattice_cx, float *lattice_cy, float *lattice_cz,
int count, int Np){
extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(
double *dist, double *zeta_potential, double *ElectricField,
double *SolidGrad, double epsilon_LB, double tau, double rho0,
double den_scale, double h, double time_conv, int *BounceBackDist_list,
int *BounceBackSolid_list, int *FluidBoundary_list, double *lattice_weight,
float *lattice_cx, float *lattice_cy, float *lattice_cz, int count,
int Np) {
int idx;
int iq, ib, ifluidBC;
@ -63,25 +70,35 @@ extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta
nsx = SolidGrad[ifluidBC + 0 * Np];
nsy = SolidGrad[ifluidBC + 1 * Np];
nsz = SolidGrad[ifluidBC + 2 * Np];
E_mag_normal = Ex*nsx+Ey*nsy+Ez*nsz;//magnitude of electric field in the direction normal to solid nodes
E_mag_normal =
Ex * nsx + Ey * nsy +
Ez *
nsz; //magnitude of electric field in the direction normal to solid nodes
//compute tangential electric field
Etx = Ex - E_mag_normal * nsx;
Ety = Ey - E_mag_normal * nsy;
Etz = Ez - E_mag_normal * nsz;
ubx = -epsilon_LB*value_b*Etx/(nu_LB*rho0)*time_conv*time_conv/(h*h*1.0e-12)/den_scale;
uby = -epsilon_LB*value_b*Ety/(nu_LB*rho0)*time_conv*time_conv/(h*h*1.0e-12)/den_scale;
ubz = -epsilon_LB*value_b*Etz/(nu_LB*rho0)*time_conv*time_conv/(h*h*1.0e-12)/den_scale;
ubx = -epsilon_LB * value_b * Etx / (nu_LB * rho0) * time_conv *
time_conv / (h * h * 1.0e-12) / den_scale;
uby = -epsilon_LB * value_b * Ety / (nu_LB * rho0) * time_conv *
time_conv / (h * h * 1.0e-12) / den_scale;
ubz = -epsilon_LB * value_b * Etz / (nu_LB * rho0) * time_conv *
time_conv / (h * h * 1.0e-12) / den_scale;
//compute bounce-back distribution
LB_weight = lattice_weight[idx];
cx = lattice_cx[idx];
cy = lattice_cy[idx];
cz = lattice_cz[idx];
dist[iq] = value_q - 2.0*LB_weight*rho0*cs2_inv*(cx*ubx+cy*uby+cz*ubz);
dist[iq] = value_q - 2.0 * LB_weight * rho0 * cs2_inv *
(cx * ubx + cy * uby + cz * ubz);
}
}
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list, double *dist, double Vin, int count, int Np){
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list,
double *dist,
double Vin, int count,
int Np) {
for (int idx = 0; idx < count; idx++) {
int n = list[idx];
double f0 = dist[n];
@ -96,7 +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++) {
int n = list[idx];
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;
for (int idx = 0; idx < count; 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;
for (int idx = 0; idx < count; 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;
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;
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++) {
int n = list[idx];
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++) {
int n = list[idx];
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;
for (int idx = 0; idx < count; 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;
for (int idx = 0; idx < count; 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
double f0, f1, f2, f3, f4, f5, f6;
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];
//...................................................
f5 =(FluxIn+(1.0-0.5/tau)*f6-0.5*uz*fsum_partial/tau)/(1.0-0.5/tau+0.5*uz/tau);
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 - 0.5 * uz * fsum_partial / tau) /
(1.0 - 0.5 / tau + 0.5 * uz / tau);
dist[6 * Np + n] = f5;
}
}
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np){
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist,
double FluxIn, double tau,
double *VelocityZ, int count,
int Np) {
//NOTE: FluxIn is the inward flux
double f0, f1, f2, f3, f4, f5, f6;
double fsum_partial;
@ -317,12 +365,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_BC_Z(int *list, double *dist, double
uz = VelocityZ[n];
//...................................................
f6 =(FluxIn+(1.0-0.5/tau)*f5+0.5*uz*fsum_partial/tau)/(1.0-0.5/tau-0.5*uz/tau);
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 + 0.5 * uz * fsum_partial / tau) /
(1.0 - 0.5 / tau - 0.5 * uz / tau);
dist[5 * Np + n] = f6;
}
}
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np){
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_BC_z(int *d_neighborList, int *list,
double *dist, double FluxIn,
double tau, double *VelocityZ,
int count, int Np) {
//NOTE: FluxIn is the inward flux
double f0, f1, f2, f3, f4, f5, f6;
double fsum_partial;
@ -351,7 +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;
uz = VelocityZ[n];
//...................................................
f5 =(FluxIn+(1.0-0.5/tau)*f6-0.5*uz*fsum_partial/tau)/(1.0-0.5/tau+0.5*uz/tau);
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 - 0.5 * uz * fsum_partial / tau) /
(1.0 - 0.5 / tau + 0.5 * uz / tau);
// Unknown distributions
nr5 = d_neighborList[n + 4 * Np];
@ -359,7 +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
double f0, f1, f2, f3, f4, f5, f6;
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;
uz = VelocityZ[n];
//...................................................
f6 =(FluxIn+(1.0-0.5/tau)*f5+0.5*uz*fsum_partial/tau)/(1.0-0.5/tau-0.5*uz/tau);
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 + 0.5 * uz * fsum_partial / tau) /
(1.0 - 0.5 / tau - 0.5 * uz / tau);
// unknown distributions
nr6 = d_neighborList[n + 5 * Np];
@ -397,8 +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
int idx, n;
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;
uz = VelocityZ[n];
//...................................................
f5 =(FluxIn+(1.0-0.5/tau)*(f6+uz*fsum_partial))/(1.0-0.5/tau)/(1.0-uz);
f5 = (FluxIn + (1.0 - 0.5 / tau) * (f6 + uz * fsum_partial)) /
(1.0 - 0.5 / tau) / (1.0 - uz);
dist[6 * Np + n] = f5;
}
}
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_Diff_BC_Z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_Diff_BC_Z(int *list, double *dist,
double FluxIn, double tau,
double *VelocityZ,
int count, int Np) {
//NOTE: FluxIn is the inward flux
int idx, n;
double f0, f1, f2, f3, f4, f5, f6;
@ -438,14 +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;
uz = VelocityZ[n];
//...................................................
f6 =(FluxIn+(1.0-0.5/tau)*(f5-uz*fsum_partial))/(1.0-0.5/tau)/(1.0+uz);
f6 = (FluxIn + (1.0 - 0.5 / tau) * (f5 - uz * fsum_partial)) /
(1.0 - 0.5 / tau) / (1.0 + uz);
dist[5 * Np + n] = f6;
}
}
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_Diff_BC_z(int *d_neighborList,
int *list, double *dist,
double FluxIn, double tau,
double *VelocityZ,
int count, int Np) {
//NOTE: FluxIn is the inward flux
int n;
int nread, nr5;
@ -476,7 +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;
uz = VelocityZ[n];
//...................................................
f5 =(FluxIn+(1.0-0.5/tau)*(f6+uz*fsum_partial))/(1.0-0.5/tau)/(1.0-uz);
f5 = (FluxIn + (1.0 - 0.5 / tau) * (f6 + uz * fsum_partial)) /
(1.0 - 0.5 / tau) / (1.0 - uz);
// Unknown distributions
nr5 = d_neighborList[n + 4 * Np];
@ -484,8 +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
int n;
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;
uz = VelocityZ[n];
//...................................................
f5 =(FluxIn+(1.0-0.5/tau)*(f6+uz*fsum_partial))/(1.0-0.5/tau)/(1.0-uz);
f5 = (FluxIn + (1.0 - 0.5 / tau) * (f6 + uz * fsum_partial)) /
(1.0 - 0.5 / tau) / (1.0 - uz);
// Unknown distributions
nr5 = d_neighborList[n + 4 * Np];
@ -522,10 +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, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_z(
int *list, double *dist, double FluxIn, double tau, double *VelocityZ,
int count, int Np) {
//NOTE: FluxIn is the inward flux
int idx, n;
double f0, f1, f2, f3, f4, f5, f6;
@ -543,13 +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;
uz = VelocityZ[n];
//...................................................
f5 =(FluxIn+(1.0-0.5/tau)*f6-0.5*uz*fsum_partial/tau)/(1.0-0.5/tau+0.5*uz/tau);
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 - 0.5 * uz * fsum_partial / tau) /
(1.0 - 0.5 / tau + 0.5 * uz / tau);
dist[6 * Np + n] = f5;
}
}
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_Z(int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvc_BC_Z(
int *list, double *dist, double FluxIn, double tau, double *VelocityZ,
int count, int Np) {
//NOTE: FluxIn is the inward flux
int idx, n;
double f0, f1, f2, f3, f4, f5, f6;
@ -566,13 +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;
uz = VelocityZ[n];
//...................................................
f6 =(FluxIn+(1.0-0.5/tau)*f5+0.5*uz*fsum_partial/tau)/(1.0-0.5/tau-0.5*uz/tau);
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 + 0.5 * uz * fsum_partial / tau) /
(1.0 - 0.5 / tau - 0.5 * uz / tau);
dist[5 * Np + n] = f6;
}
}
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvc_BC_z(
int *d_neighborList, int *list, double *dist, double FluxIn, double tau,
double *VelocityZ, int count, int Np) {
//NOTE: FluxIn is the inward flux
int idx, n;
int nread, nr5;
@ -601,7 +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;
uz = VelocityZ[n];
//...................................................
f5 =(FluxIn+(1.0-0.5/tau)*f6-0.5*uz*fsum_partial/tau)/(1.0-0.5/tau+0.5*uz/tau);
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 - 0.5 * uz * fsum_partial / tau) /
(1.0 - 0.5 / tau + 0.5 * uz / tau);
// Unknown distributions
nr5 = d_neighborList[n + 4 * Np];
@ -609,8 +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
int idx, n;
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;
uz = VelocityZ[n];
//...................................................
f6 =(FluxIn+(1.0-0.5/tau)*f5+0.5*uz*fsum_partial/tau)/(1.0-0.5/tau-0.5*uz/tau);
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 + 0.5 * uz * fsum_partial / tau) /
(1.0 - 0.5 / tau - 0.5 * uz / tau);
// unknown distributions
nr6 = d_neighborList[n + 5 * Np];
@ -647,9 +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,
double Di, double zi, double Vt, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_z(
int *list, double *dist, double FluxIn, double tau, double *VelocityZ,
double *ElectricField_Z, double Di, double zi, double Vt, int count,
int Np) {
//NOTE: FluxIn is the inward flux
int idx, n;
double f0, f1, f2, f3, f4, f5, f6;
@ -670,15 +747,17 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_z(int *list, double
Ez = ElectricField_Z[n];
uEPz = zi * Di / Vt * Ez;
//...................................................
f6 =(FluxIn+(1.0-0.5/tau)*f5+(0.5*uz/tau+uEPz)*fsum_partial)/(1.0-0.5/tau-0.5*uz/tau-uEPz);
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 +
(0.5 * uz / tau + uEPz) * fsum_partial) /
(1.0 - 0.5 / tau - 0.5 * uz / tau - uEPz);
dist[5 * Np + n] = f6;
}
}
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, double *ElectricField_Z,
double Di, double zi, double Vt, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(
int *d_neighborList, int *list, double *dist, double FluxIn, double tau,
double *VelocityZ, double *ElectricField_Z, double Di, double zi, double Vt,
int count, int Np) {
//NOTE: FluxIn is the inward flux
int idx, n;
int nread, nr5;
@ -711,7 +790,9 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_z(int *d_neighborList
Ez = ElectricField_Z[n];
uEPz = zi * Di / Vt * Ez;
//...................................................
f5 =(FluxIn+(1.0-0.5/tau)*f6-(0.5*uz/tau+uEPz)*fsum_partial)/(1.0-0.5/tau+0.5*uz/tau+uEPz);
f5 = (FluxIn + (1.0 - 0.5 / tau) * f6 -
(0.5 * uz / tau + uEPz) * fsum_partial) /
(1.0 - 0.5 / tau + 0.5 * uz / tau + uEPz);
// Unknown distributions
nr5 = d_neighborList[n + 4 * Np];
@ -719,9 +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,
double Di, double zi, double Vt, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_Z(
int *list, double *dist, double FluxIn, double tau, double *VelocityZ,
double *ElectricField_Z, double Di, double zi, double Vt, int count,
int Np) {
//NOTE: FluxIn is the inward flux
int idx, n;
double f0, f1, f2, f3, f4, f5, f6;
@ -742,13 +824,16 @@ extern "C" void ScaLBL_D3Q7_AAeven_Ion_Flux_DiffAdvcElec_BC_Z(int *list, double
Ez = ElectricField_Z[n];
uEPz = zi * Di / Vt * Ez;
//...................................................
f6 =(FluxIn+(1.0-0.5/tau)*f5+(0.5*uz/tau+uEPz)*fsum_partial)/(1.0-0.5/tau-0.5*uz/tau-uEPz);
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 +
(0.5 * uz / tau + uEPz) * fsum_partial) /
(1.0 - 0.5 / tau - 0.5 * uz / tau - uEPz);
dist[5 * Np + n] = f6;
}
}
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_Z(int *d_neighborList, int *list, double *dist, double FluxIn, double tau, double *VelocityZ, double *ElectricField_Z,
double Di, double zi, double Vt, int count, int Np)
{
extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_Z(
int *d_neighborList, int *list, double *dist, double FluxIn, double tau,
double *VelocityZ, double *ElectricField_Z, double Di, double zi, double Vt,
int count, int Np) {
//NOTE: FluxIn is the inward flux
int idx, n;
int nread, nr6;
@ -781,21 +866,12 @@ extern "C" void ScaLBL_D3Q7_AAodd_Ion_Flux_DiffAdvcElec_BC_Z(int *d_neighborList
Ez = ElectricField_Z[n];
uEPz = zi * Di / Vt * Ez;
//...................................................
f6 =(FluxIn+(1.0-0.5/tau)*f5+(0.5*uz/tau+uEPz)*fsum_partial)/(1.0-0.5/tau-0.5*uz/tau-uEPz);
f6 = (FluxIn + (1.0 - 0.5 / tau) * f5 +
(0.5 * uz / tau + uEPz) * fsum_partial) /
(1.0 - 0.5 / tau - 0.5 * uz / tau - uEPz);
// unknown distributions
nr6 = d_neighborList[n + 5 * Np];
dist[nr6] = f6;
}
}

View File

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

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>
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;
double fq, Ci;
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;
double fq, Ci;
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,
double Di, int zi, double rlx, double Vt, int start, int finish, int Np){
extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, 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;
double Ci;
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;
// 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
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
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
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
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
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,
double Di, int zi, double rlx, double Vt, int start, int finish, int Np){
extern "C" void ScaLBL_D3Q7_AAeven_Ion(
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;
double Ci;
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;
// 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
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
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
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
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
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;
for (n = 0; n < Np; n++) {
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;
double DenInit;
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;
double Ci; //ion concentration of species i
double CD; //charge density
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++) {
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;
}
}

View File

@ -14,8 +14,8 @@
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;
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_odd[8 * N + n] = 0.0277777777777778; //double(100*n)+17.f;
f_even[9 * N + n] = 0.0277777777777778; //double(100*n)+18.f;
}
else{
} else {
for (int q = 0; q < 9; q++) {
f_even[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;
}
}
}
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;
// distributions
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[2 * N + n] = vz;
//........................................................................
}
}
}
//*************************************************************************
extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd, int Nx, int Ny, int Nz,
double rlx_setA, double rlx_setB, double Fx, double Fy, double Fz)
{
extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd,
int Nx, int Ny, int Nz, double rlx_setA,
double rlx_setB, double Fx, double Fy,
double Fz) {
int n, N;
// distributions
@ -149,19 +146,27 @@ extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd, in
f17 = disteven[9 * N + n];
//........................................................................
//....................compute the moments...............................................
rho = f0+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;
rho = f0 + 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;
m4 = 4 * (-f1 + f2) + f7 - f8 + f9 - f10 + f11 - f12 + f13 - f14;
jy = 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;
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);
m10 = -4*(f1+f2)+2*(f4+f3+f6+f5)+f8+f7+f10+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;
m9 = 2 * (f1 + f2) - f3 - f4 - f5 - f6 + f7 + f8 + f9 + f10 + f11 +
f12 + f13 + f14 - 2 * (f15 + f16 + f17 + f18);
m10 = -4 * (f1 + f2) + 2 * (f4 + f3 + f6 + f5) + f8 + f7 + f10 +
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;
m14 = f16 + f15 - f18 - f17;
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;
//jz += 0.5*Fz;
//..............carry out relaxation process...............................................
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1);
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2);
m1 = m1 + rlx_setA * ((19 * (jx * jx + jy * jy + jz * jz) / rho -
11 * rho) -
m1);
m2 = m2 + rlx_setA * ((3 * rho -
5.5 * (jx * jx + jy * jy + jz * jz) / rho) -
m2);
m4 = m4 + rlx_setB * ((-0.6666666666666666 * jx) - m4);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/rho) - m9);
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
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);
m11 = m11 + rlx_setA * (((jy * jy - jz * jz) / rho) - m11);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho) - m12);
m13 = m13 + rlx_setA * ((jx * jy / rho) - m13);
@ -189,59 +201,86 @@ extern "C" void ScaLBL_D3Q19_MRT(char *ID, double *disteven, double *distodd, in
m17 = m17 + rlx_setB * (-m17);
m18 = m18 + rlx_setB * (-m18);
//.................inverse transformation......................................................
f0 = 0.05263157894736842*rho-0.012531328320802*m1+0.04761904761904762*m2;
f1 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2
+0.1*(jx-m4)+0.05555555555555555*(m9-m10);
f2 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2
+0.1*(m4-jx)+0.05555555555555555*(m9-m10);
f3 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2
+0.1*(jy-m6)+0.02777777777777778*(m10-m9)+0.08333333333333333*(m11-m12);
f4 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2
+0.1*(m6-jy)+0.02777777777777778*(m10-m9)+0.08333333333333333*(m11-m12);
f5 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2
+0.1*(jz-m8)+0.02777777777777778*(m10-m9)+0.08333333333333333*(m12-m11);
f6 = 0.05263157894736842*rho-0.004594820384294068*m1-0.01587301587301587*m2
+0.1*(m8-jz)+0.02777777777777778*(m10-m9)+0.08333333333333333*(m12-m11);
f7 = 0.05263157894736842*rho+0.003341687552213868*m1+0.003968253968253968*m2+0.1*(jx+jy)+0.025*(m4+m6)
+0.02777777777777778*m9+0.01388888888888889*m10+0.08333333333333333*m11
+0.04166666666666666*m12+0.25*m13+0.125*(m16-m17);
f8 = 0.05263157894736842*rho+0.003341687552213868*m1+0.003968253968253968*m2-0.1*(jx+jy)-0.025*(m4+m6)
+0.02777777777777778*m9+0.01388888888888889*m10+0.08333333333333333*m11
+0.04166666666666666*m12+0.25*m13+0.125*(m17-m16);
f9 = 0.05263157894736842*rho+0.003341687552213868*m1+0.003968253968253968*m2+0.1*(jx-jy)+0.025*(m4-m6)
+0.02777777777777778*m9+0.01388888888888889*m10+0.08333333333333333*m11
+0.04166666666666666*m12-0.25*m13+0.125*(m16+m17);
f10 = 0.05263157894736842*rho+0.003341687552213868*m1+0.003968253968253968*m2+0.1*(jy-jx)+0.025*(m6-m4)
+0.02777777777777778*m9+0.01388888888888889*m10+0.08333333333333333*m11
+0.04166666666666666*m12-0.25*m13-0.125*(m16+m17);
f11 = 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*(m18-m16);
f12 = 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);
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);
f0 = 0.05263157894736842 * rho - 0.012531328320802 * m1 +
0.04761904761904762 * m2;
f1 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
0.01587301587301587 * m2 + 0.1 * (jx - m4) +
0.05555555555555555 * (m9 - m10);
f2 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
0.01587301587301587 * m2 + 0.1 * (m4 - jx) +
0.05555555555555555 * (m9 - m10);
f3 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
0.01587301587301587 * m2 + 0.1 * (jy - m6) +
0.02777777777777778 * (m10 - m9) +
0.08333333333333333 * (m11 - m12);
f4 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
0.01587301587301587 * m2 + 0.1 * (m6 - jy) +
0.02777777777777778 * (m10 - m9) +
0.08333333333333333 * (m11 - m12);
f5 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
0.01587301587301587 * m2 + 0.1 * (jz - m8) +
0.02777777777777778 * (m10 - m9) +
0.08333333333333333 * (m12 - m11);
f6 = 0.05263157894736842 * rho - 0.004594820384294068 * m1 -
0.01587301587301587 * m2 + 0.1 * (m8 - jz) +
0.02777777777777778 * (m10 - m9) +
0.08333333333333333 * (m12 - m11);
f7 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 + 0.1 * (jx + jy) +
0.025 * (m4 + m6) + 0.02777777777777778 * m9 +
0.01388888888888889 * m10 + 0.08333333333333333 * m11 +
0.04166666666666666 * m12 + 0.25 * m13 + 0.125 * (m16 - m17);
f8 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 - 0.1 * (jx + jy) -
0.025 * (m4 + m6) + 0.02777777777777778 * m9 +
0.01388888888888889 * m10 + 0.08333333333333333 * m11 +
0.04166666666666666 * m12 + 0.25 * m13 + 0.125 * (m17 - m16);
f9 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 + 0.1 * (jx - jy) +
0.025 * (m4 - m6) + 0.02777777777777778 * m9 +
0.01388888888888889 * m10 + 0.08333333333333333 * m11 +
0.04166666666666666 * m12 - 0.25 * m13 + 0.125 * (m16 + m17);
f10 = 0.05263157894736842 * rho + 0.003341687552213868 * m1 +
0.003968253968253968 * m2 + 0.1 * (jy - jx) +
0.025 * (m6 - m4) + 0.02777777777777778 * m9 +
0.01388888888888889 * m10 + 0.08333333333333333 * m11 +
0.04166666666666666 * m12 - 0.25 * m13 - 0.125 * (m16 + m17);
f11 = 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 * (m18 - m16);
f12 = 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);
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
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)*/
extern "C" void ScaLBL_D3Q19_MixedGradient(int *Map, double *Phi, double *Gradient, int start, int finish, int Np, int Nx, int Ny, int Nz)
{
static int D3Q19[18][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1},
{1,1,0},{-1,-1,0},{1,-1,0},{-1,1,0},
{1,0,1},{-1,0,-1},{1,0,-1},{-1,0,1},
{0,1,1},{0,-1,-1},{0,1,-1},{0,-1,1}};
extern "C" void ScaLBL_D3Q19_MixedGradient(int *Map, double *Phi,
double *Gradient, int start,
int finish, int Np, int Nx, int Ny,
int Nz) {
static int D3Q19[18][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0},
{0, 0, 1}, {0, 0, -1}, {1, 1, 0}, {-1, -1, 0},
{1, -1, 0}, {-1, 1, 0}, {1, 0, 1}, {-1, 0, -1},
{1, 0, -1}, {-1, 0, 1}, {0, 1, 1}, {0, -1, -1},
{0, 1, -1}, {0, -1, 1}};
int i, j, k, n;
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;
double psi; //electric potential
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;
double psi; //electric potential
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;
double psi; //electric potential
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];
f6 = dist[nr6];
Ex = (f1-f2)*rlx*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
Ex = (f1 - f2) * rlx *
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;
ElectricField[n + 0 * Np] = Ex;
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;
double psi; //electric potential
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];
f6 = dist[5 * Np + n];
Ex = (f1-f2)*rlx*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
Ex = (f1 - f2) * rlx *
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;
ElectricField[n + 0 * Np] = Ex;
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 ijk;
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;
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)
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;
ResidualError[n] = residual_error;
}

View File

@ -1,7 +1,10 @@
#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;
// conserved momemnts
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];
Ez = ElectricField[n + 2 * Np];
//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
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;
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
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
fq = dist[n];
@ -317,7 +325,6 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
Velocity[Np + n] = uy;
Velocity[2 * Np + n] = uz;
//........................................................................
// READ THE DISTRIBUTIONS
// (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................................................
//..............carry out relaxation process...............................................
m1 = m1 + 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);
m1 = m1 +
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);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / 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);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho0) - m12);
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;
// q = 1
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10) + 0.16666666*Fx;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jx - m4) +
mrt_V6 * (m9 - m10) + 0.16666666 * Fx;
dist[1 * Np + n] = fq;
// q=2
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10) - 0.16666666*Fx;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m4 - jx) +
mrt_V6 * (m9 - m10) - 0.16666666 * Fx;
dist[2 * Np + n] = fq;
// q = 3
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) + 0.16666666*Fy;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jy - m6) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) + 0.16666666 * Fy;
dist[3 * Np + n] = fq;
// q = 4
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) - 0.16666666*Fy;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m6 - jy) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) - 0.16666666 * Fy;
dist[4 * Np + n] = fq;
// q = 5
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) + 0.16666666*Fz;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jz - m8) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) + 0.16666666 * Fz;
dist[5 * Np + n] = fq;
// q = 6
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) - 0.16666666*Fz;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m8 - jz) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) - 0.16666666 * Fz;
dist[6 * Np + n] = fq;
// q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(Fx+Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (Fx + Fy);
dist[7 * Np + n] = fq;
// q = 8
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m17 - m16) -
0.08333333333 * (Fx + Fy);
dist[8 * Np + n] = fq;
// q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(Fx-Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
0.025 * (m4 - m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (Fx - Fy);
dist[9 * Np + n] = fq;
// q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(Fx-Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
0.025 * (m6 - m4) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (Fx - Fy);
dist[10 * Np + n] = fq;
// q = 11
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
0.08333333333 * (Fx + Fz);
dist[11 * Np + n] = fq;
// q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m16-m18) - 0.08333333333*(Fx+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (Fx + Fz);
dist[12 * Np + n] = fq;
// q = 13
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
0.08333333333 * (Fx - Fz);
dist[13 * Np + n] = fq;
// q= 14
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
0.08333333333 * (Fx - Fz);
dist[14 * Np + n] = fq;
// q = 15
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
dist[15 * Np + n] = fq;
// q = 16
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
dist[16 * Np + n] = fq;
// q = 17
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8)
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
dist[17 * Np + n] = fq;
// q = 18
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6)
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
dist[18 * Np + n] = fq;
//........................................................................
}
}
extern "C" void ScaLBL_D3Q19_AAodd_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;
// conserved momemnts
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];
Ez = ElectricField[n + 2 * Np];
//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;
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;
Fx = Gx + rhoE * Ex * (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
fq = dist[n];
@ -512,7 +540,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
m10 = -4.0 * fq;
// f2 = dist[10*Np+n];
nread = neighborList[n+Np]; // neighbor 1 ( < 10Np => even part of dist)
nread =
neighborList[n + Np]; // neighbor 1 ( < 10Np => even part of dist)
fq = dist[nread]; // reading the f2 data into register fq
//fq = dist[Np+n];
rho += fq;
@ -565,7 +594,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
m11 -= fq;
m12 += 2.0 * fq;
// q = 6
nread = neighborList[n + 5 * Np];
fq = dist[nread];
@ -810,13 +838,19 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
//..............incorporate external force................................................
//..............carry out relaxation process...............................................
m1 = m1 + 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);
m1 = m1 +
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);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA * (((2 * jx * jx - jy * jy - jz * jz) / 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);
m12 = m12 + rlx_setA * (-0.5 * ((jy * jy - jz * jz) / rho0) - m12);
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;
// q = 1
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10)+0.16666666*Fx;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jx - m4) +
mrt_V6 * (m9 - m10) + 0.16666666 * Fx;
nread = neighborList[n + Np];
dist[nread] = fq;
// q=2
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m4-jx)+mrt_V6*(m9-m10) - 0.16666666*Fx;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m4 - jx) +
mrt_V6 * (m9 - m10) - 0.16666666 * Fx;
nread = neighborList[n];
dist[nread] = fq;
// q = 3
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) + 0.16666666*Fy;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jy - m6) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) + 0.16666666 * Fy;
nread = neighborList[n + 3 * Np];
dist[nread] = fq;
// q = 4
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) - 0.16666666*Fy;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m6 - jy) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m11 - m12) - 0.16666666 * Fy;
nread = neighborList[n + 2 * Np];
dist[nread] = fq;
// q = 5
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) + 0.16666666*Fz;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (jz - m8) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) + 0.16666666 * Fz;
nread = neighborList[n + 5 * Np];
dist[nread] = fq;
// q = 6
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) - 0.16666666*Fz;
fq = mrt_V1 * rho - mrt_V4 * m1 - mrt_V5 * m2 + 0.1 * (m8 - jz) +
mrt_V7 * (m10 - m9) + mrt_V8 * (m12 - m11) - 0.16666666 * Fz;
nread = neighborList[n + 4 * Np];
dist[nread] = fq;
// q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(Fx+Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (Fx + Fy);
nread = neighborList[n + 7 * Np];
dist[nread] = fq;
// q = 8
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(Fx+Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m17 - m16) -
0.08333333333 * (Fx + Fy);
nread = neighborList[n + 6 * Np];
dist[nread] = fq;
// q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(Fx-Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
0.025 * (m4 - m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (Fx - Fy);
nread = neighborList[n + 9 * Np];
dist[nread] = fq;
// q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)
+mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(Fx-Fy);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
0.025 * (m6 - m4) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (Fx - Fy);
nread = neighborList[n + 8 * Np];
dist[nread] = fq;
// q = 11
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(Fx+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
0.08333333333 * (Fx + Fz);
nread = neighborList[n + 11 * Np];
dist[nread] = fq;
// q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m16-m18) - 0.08333333333*(Fx+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (Fx + Fz);
nread = neighborList[n + 10 * Np];
dist[nread] = fq;
// q = 13
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(Fx-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
0.08333333333 * (Fx - Fz);
nread = neighborList[n + 13 * Np];
dist[nread] = fq;
// q= 14
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(Fx-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
0.08333333333 * (Fx - Fz);
nread = neighborList[n + 12 * Np];
dist[nread] = fq;
// q = 15
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(Fy+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m17 - m18) + 0.08333333333 * (Fy + Fz);
nread = neighborList[n + 15 * Np];
dist[nread] = fq;
// q = 16
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(Fy+Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m18 - m17) - 0.08333333333 * (Fy + Fz);
nread = neighborList[n + 14 * Np];
dist[nread] = fq;
// q = 17
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8)
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(Fy-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
0.125 * (m17 + m18) + 0.08333333333 * (Fy - Fz);
nread = neighborList[n + 17 * Np];
dist[nread] = fq;
// q = 18
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6)
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(Fy-Fz);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
0.125 * (m17 + m18) - 0.08333333333 * (Fy - Fz);
nread = neighborList[n + 16 * Np];
dist[nread] = fq;
}
}

View File

@ -33,8 +33,10 @@
#include <math.h>
#include <stdio.h>
extern "C" void ScaLBL_Gradient_Unpack(double weight, double Cqx, double Cqy, double Cqz,
int *list, int start, int count, double *recvbuf, double *phi, double *grad, int N){
extern "C" void ScaLBL_Gradient_Unpack(double weight, double Cqx, double Cqy,
double Cqz, int *list, int start,
int count, double *recvbuf, double *phi,
double *grad, int N) {
//....................................................................................
// unpack halo and incorporate into D3Q19 based gradient
// 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++) {
double phi, nA, nB;
phi = Phi[idx];
if (phi > 0.f) {
nA = 1.0; nB = 0.f;
}
else{
nB = 1.0; nA = 0.f;
nA = 1.0;
nB = 0.f;
} else {
nB = 1.0;
nA = 0.f;
}
Den[idx] = nA;
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
extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double *Aq, double *Bq, double *Den, 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)
{
extern "C" void ScaLBL_D3Q19_AAeven_DFH(
int *neighborList, double *dist, double *Aq, double *Bq, double *Den,
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;
// conserved momemnts
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_V12 = 0.04166666666666666;
for (int n = start; n < finish; n++) {
// 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];
nz = Gradient[n + 2 * Np];
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;
ny = ny / C;
nz = nz / C;
@ -418,24 +421,35 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
//........................................................................
//..............carry out relaxation process..............................
//..........Toelke, Fruediger et. al. 2006................................
if (C == 0.0) nx = ny = nz = 0.0;
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);
if (C == 0.0)
nx = ny = nz = 0.0;
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);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/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);
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);
m13 = m13 + rlx_setA*( (jx*jy/rho0) + 0.5*alpha*C*nx*ny - m13);
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);
m13 = m13 +
rlx_setA * ((jx * jy / rho0) + 0.5 * alpha * C * nx * ny - m13);
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);
m17 = m17 + rlx_setB * (-m17);
m18 = m18 + rlx_setB * (-m18);
//.......................................................................................................
// assign force with wetting BC
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;
// 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;
// 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;
// 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;
// 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;
// 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;
// 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;
// q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)+
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(force_x+force_y);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (force_x + force_y);
dist[7 * Np + n] = fq;
// q = 8
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(force_x+force_y);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m17 - m16) -
0.08333333333 * (force_x + force_y);
dist[8 * Np + n] = fq;
// q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)+
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(force_x-force_y);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
0.025 * (m4 - m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (force_x - force_y);
dist[9 * Np + n] = fq;
// q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)+
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(force_x-force_y);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
0.025 * (m6 - m4) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (force_x - force_y);
dist[10 * Np + n] = fq;
// q = 11
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(force_x+force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
0.08333333333 * (force_x + force_z);
dist[11 * Np + n] = fq;
// q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)+
mrt_V7*m9+mrt_V11*m10-mrt_V8*m11-mrt_V12*m12+0.25*m15+0.125*(m16-m18)-0.08333333333*(force_x+force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (force_x + force_z);
dist[12 * Np + n] = fq;
// q = 13
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(force_x-force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
0.08333333333 * (force_x - force_z);
dist[13 * Np + n] = fq;
// q= 14
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(force_x-force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
0.08333333333 * (force_x - force_z);
dist[14 * Np + n] = fq;
// q = 15
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(force_y+force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m17 - m18) + 0.08333333333 * (force_y + force_z);
dist[15 * Np + n] = fq;
// q = 16
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(force_y+force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m18 - m17) - 0.08333333333 * (force_y + force_z);
dist[16 * Np + n] = fq;
// q = 17
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8)
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(force_y-force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
0.125 * (m17 + m18) + 0.08333333333 * (force_y - force_z);
dist[17 * Np + n] = fq;
// q = 18
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6)
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(force_y-force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
0.125 * (m17 + m18) - 0.08333333333 * (force_y - force_z);
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
// Cq = {1,0,0}, {0,1,0}, {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nx;
if (!(nA*nB*nAB>0)) delta=0;
if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (0.1111111111111111 * (1 + 4.5 * ux)) + delta;
b1 = nB * (0.1111111111111111 * (1 + 4.5 * ux)) - delta;
a2 = nA * (0.1111111111111111 * (1 - 4.5 * ux)) - delta;
@ -581,7 +609,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
// q = 2
// Cq = {0,1,0}
delta = beta * nA * nB * nAB * 0.1111111111111111 * ny;
if (!(nA*nB*nAB>0)) delta=0;
if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (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;
@ -595,7 +624,8 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
// q = 4
// Cq = {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nz;
if (!(nA*nB*nAB>0)) delta=0;
if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (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;
@ -606,14 +636,14 @@ extern "C" void ScaLBL_D3Q19_AAeven_DFH(int *neighborList, double *dist, double
Aq[6 * Np + n] = a2;
Bq[6 * Np + n] = b2;
//...............................................
}
}
}
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 tauA, double tauB, double alpha, double beta,
double Fx, double Fy, double Fz, int start, int finish, int Np){
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 tauA, double tauB, double alpha, double beta, double Fx, double Fy,
double Fz, int start, int finish, int Np) {
int nread;
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];
nz = Gradient[n + 2 * Np];
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;
ny = ny / C;
nz = nz / C;
@ -748,7 +779,6 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
m11 -= fq;
m12 += 2.0 * fq;
// q = 6
//nread = neighborList[n+5*Np];
//fq = dist[nread];
@ -995,19 +1025,31 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
//........................................................................
//..............carry out relaxation process..............................
//..........Toelke, Fruediger et. al. 2006................................
if (C == 0.0) nx = ny = nz = 0.0;
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);
if (C == 0.0)
nx = ny = nz = 0.0;
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);
m6 = m6 + rlx_setB * ((-0.6666666666666666 * jy) - m6);
m8 = m8 + rlx_setB * ((-0.6666666666666666 * jz) - m8);
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/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);
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);
m13 = m13 + rlx_setA*( (jx*jy/rho0) + 0.5*alpha*C*nx*ny - m13);
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);
m13 = m13 +
rlx_setA * ((jx * jy / rho0) + 0.5 * alpha * C * nx * ny - m13);
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);
m17 = m17 + rlx_setB * (-m17);
m18 = m18 + rlx_setB * (-m18);
@ -1023,116 +1065,130 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
dist[n] = fq;
// q = 1
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jx-m4)+mrt_V6*(m9-m10)+0.16666666*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];
dist[nr2] = fq;
// 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];
dist[nr1] = fq;
// q = 3
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jy-m6)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) + 0.16666666*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];
dist[nr4] = fq;
// q = 4
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m6-jy)+mrt_V7*(m10-m9)+mrt_V8*(m11-m12) - 0.16666666*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];
dist[nr3] = fq;
// q = 5
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(jz-m8)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) + 0.16666666*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];
dist[nr6] = fq;
// q = 6
fq = mrt_V1*rho-mrt_V4*m1-mrt_V5*m2+0.1*(m8-jz)+mrt_V7*(m10-m9)+mrt_V8*(m12-m11) - 0.16666666*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];
dist[nr5] = fq;
// q = 7
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx+jy)+0.025*(m4+m6)+
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12+0.25*m13+0.125*(m16-m17) + 0.08333333333*(force_x+force_y);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jy) +
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m16 - m17) +
0.08333333333 * (force_x + force_y);
//nread = neighborList[n+7*Np];
dist[nr8] = fq;
// q = 8
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jy)-0.025*(m4+m6) +mrt_V7*m9+mrt_V11*m10+mrt_V8*m11
+mrt_V12*m12+0.25*m13+0.125*(m17-m16) - 0.08333333333*(force_x+force_y);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jy) -
0.025 * (m4 + m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 + 0.25 * m13 + 0.125 * (m17 - m16) -
0.08333333333 * (force_x + force_y);
//nread = neighborList[n+6*Np];
dist[nr7] = fq;
// q = 9
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jx-jy)+0.025*(m4-m6)+
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13+0.125*(m16+m17) + 0.08333333333*(force_x-force_y);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jy) +
0.025 * (m4 - m6) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 + 0.125 * (m16 + m17) +
0.08333333333 * (force_x - force_y);
//nread = neighborList[n+9*Np];
dist[nr10] = fq;
// q = 10
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2+0.1*(jy-jx)+0.025*(m6-m4)+
mrt_V7*m9+mrt_V11*m10+mrt_V8*m11+mrt_V12*m12-0.25*m13-0.125*(m16+m17)- 0.08333333333*(force_x-force_y);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jx) +
0.025 * (m6 - m4) + mrt_V7 * m9 + mrt_V11 * m10 + mrt_V8 * m11 +
mrt_V12 * m12 - 0.25 * m13 - 0.125 * (m16 + m17) -
0.08333333333 * (force_x - force_y);
//nread = neighborList[n+8*Np];
dist[nr9] = fq;
// q = 11
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx+jz)+0.025*(m4+m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12+0.25*m15+0.125*(m18-m16) + 0.08333333333*(force_x+force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx + jz) +
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m18 - m16) +
0.08333333333 * (force_x + force_z);
//nread = neighborList[n+11*Np];
dist[nr12] = fq;
// q = 12
fq = mrt_V1*rho+mrt_V9*m1+mrt_V10*m2-0.1*(jx+jz)-0.025*(m4+m8)+
mrt_V7*m9+mrt_V11*m10-mrt_V8*m11-mrt_V12*m12+0.25*m15+0.125*(m16-m18) - 0.08333333333*(force_x+force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jx + jz) -
0.025 * (m4 + m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 + 0.25 * m15 + 0.125 * (m16 - m18) -
0.08333333333 * (force_x + force_z);
//nread = neighborList[n+10*Np];
dist[nr11] = fq;
// q = 13
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jx-jz)+0.025*(m4-m8)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15-0.125*(m16+m18) + 0.08333333333*(force_x-force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jx - jz) +
0.025 * (m4 - m8) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 - 0.125 * (m16 + m18) +
0.08333333333 * (force_x - force_z);
//nread = neighborList[n+13*Np];
dist[nr14] = fq;
// q= 14
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jx)+0.025*(m8-m4)
+mrt_V7*m9+mrt_V11*m10-mrt_V8*m11
-mrt_V12*m12-0.25*m15+0.125*(m16+m18) - 0.08333333333*(force_x-force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jx) +
0.025 * (m8 - m4) + mrt_V7 * m9 + mrt_V11 * m10 - mrt_V8 * m11 -
mrt_V12 * m12 - 0.25 * m15 + 0.125 * (m16 + m18) -
0.08333333333 * (force_x - force_z);
//nread = neighborList[n+12*Np];
dist[nr13] = fq;
// q = 15
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy+jz)+0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m17-m18) + 0.08333333333*(force_y+force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy + jz) +
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m17 - m18) + 0.08333333333 * (force_y + force_z);
nread = neighborList[n + 15 * Np];
dist[nread] = fq;
// q = 16
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2-0.1*(jy+jz)-0.025*(m6+m8)
-mrt_V6*m9-mrt_V7*m10+0.25*m14+0.125*(m18-m17)- 0.08333333333*(force_y+force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 - 0.1 * (jy + jz) -
0.025 * (m6 + m8) - mrt_V6 * m9 - mrt_V7 * m10 + 0.25 * m14 +
0.125 * (m18 - m17) - 0.08333333333 * (force_y + force_z);
nread = neighborList[n + 14 * Np];
dist[nread] = fq;
// q = 17
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jy-jz)+0.025*(m6-m8)
-mrt_V6*m9-mrt_V7*m10-0.25*m14+0.125*(m17+m18) + 0.08333333333*(force_y-force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jy - jz) +
0.025 * (m6 - m8) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 +
0.125 * (m17 + m18) + 0.08333333333 * (force_y - force_z);
nread = neighborList[n + 17 * Np];
dist[nread] = fq;
// q = 18
fq = mrt_V1*rho+mrt_V9*m1
+mrt_V10*m2+0.1*(jz-jy)+0.025*(m8-m6)
-mrt_V6*m9-mrt_V7*m10-0.25*m14-0.125*(m17+m18) - 0.08333333333*(force_y-force_z);
fq = mrt_V1 * rho + mrt_V9 * m1 + mrt_V10 * m2 + 0.1 * (jz - jy) +
0.025 * (m8 - m6) - mrt_V6 * m9 - mrt_V7 * m10 - 0.25 * m14 -
0.125 * (m17 + m18) - 0.08333333333 * (force_y - force_z);
nread = neighborList[n + 16 * Np];
dist[nread] = fq;
@ -1154,7 +1210,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
// q = 0,2,4
// Cq = {1,0,0}, {0,1,0}, {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nx;
if (!(nA*nB*nAB>0)) delta=0;
if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (0.1111111111111111 * (1 + 4.5 * ux)) + delta;
b1 = nB * (0.1111111111111111 * (1 + 4.5 * ux)) - delta;
a2 = nA * (0.1111111111111111 * (1 - 4.5 * ux)) - delta;
@ -1172,7 +1229,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
//...............................................
// Cq = {0,1,0}
delta = beta * nA * nB * nAB * 0.1111111111111111 * ny;
if (!(nA*nB*nAB>0)) delta=0;
if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (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;
@ -1191,7 +1249,8 @@ extern "C" void ScaLBL_D3Q19_AAodd_DFH(int *neighborList, double *dist, double *
// q = 4
// Cq = {0,0,1}
delta = beta * nA * nB * nAB * 0.1111111111111111 * nz;
if (!(nA*nB*nAB>0)) delta=0;
if (!(nA * nB * nAB > 0))
delta = 0;
a1 = nA * (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;
@ -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,
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++) {
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,
int start, int finish, int Np)
{
extern "C" void ScaLBL_D3Q7_AAeven_DFH(double *Aq, double *Bq, double *Den,
double *Phi, int start, int finish,
int Np) {
for (int n = start; n < finish; n++) {
double fq, nA, nB;
// 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;
// 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
// 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 "threadpool/thread_pool.h"
#ifndef ScaLBL_ColorModel_INC
#define ScaLBL_ColorModel_INC
@ -166,4 +165,3 @@ private:
};
#endif

View File

@ -3,16 +3,13 @@ color lattice boltzmann model
*/
#include "models/DFHModel.h"
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),
Fx(0),Fy(0),Fz(0),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(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), Fx(0), Fy(0), Fz(0),
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() {}
/*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) {
// read the input database
db = std::make_shared<Database>(filename);
@ -84,8 +80,7 @@ void ScaLBL_DFHModel::ReadParams(string filename){
BoundaryCondition = domain_db->getScalar<int>("BC");
if (color_db->keyExists("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");
}
@ -103,17 +98,25 @@ void ScaLBL_DFHModel::ReadParams(string filename){
nprocy = nproc[1];
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() {
Dm = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // full domain for analysis
Mask = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // mask domain removes immobile phases
Nx+=2; Ny+=2; Nz += 2;
Dm = std::shared_ptr<Domain>(
new Domain(domain_db, comm)); // full domain for analysis
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;
id = new char[N];
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
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
comm.barrier();
Dm->CommInit();
comm.barrier();
@ -122,10 +125,12 @@ void ScaLBL_DFHModel::SetDomain(){
void ScaLBL_DFHModel::ReadInput() {
//.......................................................................
if (rank == 0) printf("Read input media... \n");
if (rank == 0)
printf("Read input media... \n");
//.......................................................................
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(LocalRankFilename, "%s%s", "ID.", LocalRankString);
@ -133,17 +138,18 @@ void ScaLBL_DFHModel::ReadInput(){
// .......... 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(LocalRankFilename, "%s%s", "SignDist.", LocalRankString);
ReadBinaryFile(LocalRankFilename, Averages->SDs.data(), N);
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;
char VALUE = 0;
double AFFINITY = 0.f;
@ -153,7 +159,8 @@ void ScaLBL_DFHModel::AssignComponentLabels(double *phase)
NLABELS = LabelList.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) {
@ -176,7 +183,8 @@ void ScaLBL_DFHModel::AssignComponentLabels(double *phase)
if (VALUE == LabelList[idx]) {
AFFINITY = AffinityList[idx];
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;
@ -184,10 +192,10 @@ void ScaLBL_DFHModel::AssignComponentLabels(double *phase)
}
}
// 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() {
/*
* This function creates the variables needed to run a LBM
@ -199,26 +207,33 @@ void ScaLBL_DFHModel::Create(){
//.........................................................
// 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();
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)
// 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;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx,Ny,Nz); Map.fill(-2);
if (rank == 0)
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];
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();
//...........................................................................
// MAIN VARIABLES ALLOCATED HERE
//...........................................................................
// LBM variables
if (rank==0) printf ("Allocating distributions \n");
if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions.................................
dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int));
@ -234,11 +249,13 @@ void ScaLBL_DFHModel::Create(){
ScaLBL_AllocateDeviceMemory((void **)&Pressure, sizeof(double) * Np);
ScaLBL_AllocateDeviceMemory((void **)&Velocity, 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
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
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
@ -262,7 +279,8 @@ void ScaLBL_DFHModel::Create(){
* AssignComponentLabels *
********************************************************/
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;
PhaseLabel = new double[Nx * Ny * Nz];
AssignComponentLabels(PhaseLabel);
@ -277,7 +295,9 @@ void ScaLBL_DFHModel::AssignSolidPotential(){
for (int jj = 0; jj < 3; jj++) {
for (int ii = 0; ii < 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 idk = k + kk - 1;
if (idi < 0) idi=0;
if (idj < 0) idj=0;
if (idk < 0) idk=0;
if (!(idi < Nx)) idi=Nx-1;
if (!(idj < Ny)) idj=Ny-1;
if (!(idk < Nz)) idk=Nz-1;
if (idi < 0)
idi = 0;
if (idj < 0)
idj = 0;
if (idk < 0)
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;
if (!(Mask->id[nn] > 0)) {
@ -432,12 +458,15 @@ void ScaLBL_DFHModel::Initialize(){
}
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)
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);
if (Restart == true) {
@ -447,8 +476,7 @@ void ScaLBL_DFHModel::Initialize(){
if (restart.is_open()) {
restart >> timestep;
printf("Restarting from timestep =%i \n", timestep);
}
else{
} else {
printf("WARNING:No Restart.txt file, setting timestep=0 \n");
timestep = 0;
}
@ -478,25 +506,29 @@ void ScaLBL_DFHModel::Initialize(){
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, 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() {
int nprocs = nprocx * nprocy * nprocz;
const RankInfoStruct rank_info(rank, nprocx, nprocy, nprocz);
if (rank==0) printf("********************************************************\n");
if (rank==0) printf("No. of timesteps: %i \n", timestepMax);
if (rank == 0)
printf("********************************************************\n");
if (rank == 0)
printf("No. of timesteps: %i \n", timestepMax);
ScaLBL_DeviceBarrier();
comm.barrier();
//************ MAIN ITERATION LOOP ***************************************/
auto t1 = std::chrono::system_clock::now();
bool Regular = true;
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) {
//if ( rank==0 ) { printf("Running timestep %i (%i MB)\n",timestep+1,(int)(Utilities::getMemoryUsage()/1048576)); }
PROFILE_START("Update");
@ -505,20 +537,28 @@ void ScaLBL_DFHModel::Run(){
// Compute the Phase indicator field
// Read for Aq, Bq happens in this routine (requires communication)
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_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
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_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);
// Perform the collision operation
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
ScaLBL_D3Q19_AAodd_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient, SolidPotential, rhoA, rhoB, tauA, tauB,
alpha, beta, Fx, Fy, Fz, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
ScaLBL_D3Q19_AAodd_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient,
SolidPotential, rhoA, rhoB, tauA, tauB, alpha,
beta, Fx, Fy, Fz, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
// Set BCs
if (BoundaryCondition > 0) {
@ -530,31 +570,42 @@ void ScaLBL_DFHModel::Run(){
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
}
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_D3Q19_AAodd_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient, SolidPotential, rhoA, rhoB, tauA, tauB,
alpha, beta, Fx, Fy, Fz, 0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_DeviceBarrier(); comm.barrier();
ScaLBL_D3Q19_AAodd_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient,
SolidPotential, rhoA, rhoB, tauA, tauB, alpha,
beta, Fx, Fy, Fz, 0, ScaLBL_Comm->LastExterior(),
Np);
ScaLBL_DeviceBarrier();
comm.barrier();
// *************EVEN TIMESTEP*************
timestep++;
// Compute the Phase indicator field
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_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
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_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);
// Perform the collision operation
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
ScaLBL_D3Q19_AAeven_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient, SolidPotential, rhoA, rhoB, tauA, tauB,
alpha, beta, Fx, Fy, Fz, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
ScaLBL_D3Q19_AAeven_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient,
SolidPotential, rhoA, rhoB, tauA, tauB, alpha,
beta, Fx, Fy, Fz, ScaLBL_Comm->FirstInterior(),
ScaLBL_Comm->LastInterior(), Np);
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
// Set boundary conditions
if (BoundaryCondition > 0) {
@ -564,20 +615,24 @@ void ScaLBL_DFHModel::Run(){
if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
}
else if (BoundaryCondition == 4){
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
} else if (BoundaryCondition == 4) {
din =
ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, 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,
alpha, beta, Fx, Fy, Fz, 0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_DeviceBarrier(); comm.barrier();
ScaLBL_D3Q19_AAeven_DFH(NeighborList, fq, Aq, Bq, Den, Phi, Gradient,
SolidPotential, rhoA, rhoB, tauA, tauB, alpha,
beta, Fx, Fy, Fz, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_DeviceBarrier();
comm.barrier();
//************************************************************************
comm.barrier();
PROFILE_STOP("Update");
// 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();
PROFILE_STOP("Loop");
@ -585,18 +640,25 @@ void ScaLBL_DFHModel::Run(){
//************************************************************************
ScaLBL_DeviceBarrier();
comm.barrier();
if (rank==0) printf("-------------------------------------------------------------------\n");
if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep;
// Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000;
if (rank==0) printf("********************************************************\n");
if (rank==0) printf("CPU time = %f \n", cputime);
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
if (rank == 0)
printf("CPU time = %f \n", cputime);
if (rank == 0)
printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
MLUPS *= nprocs;
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank==0) printf("********************************************************\n");
if (rank == 0)
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");
fwrite(PhaseField.data(), 8, N, BFILE);
fclose(BFILE);
}

View File

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

View File

@ -9,18 +9,15 @@ color lattice boltzmann model
#include <stdlib.h>
#include <time.h>
ScaLBL_FreeLeeModel::ScaLBL_FreeLeeModel(int RANK, int NP, const Utilities::MPI& COMM):
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),
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(int RANK, int NP,
const Utilities::MPI &COMM)
: 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), 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() {}
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->Barrier(); comm.barrier();
ScaLBL_Comm->Barrier();
comm.barrier();
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->Barrier(); comm.barrier();
ScaLBL_Comm->Barrier();
comm.barrier();
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->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
// Primarly for debugging
int i, j, k, idx;
@ -102,7 +106,8 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
//beta = 12.0*gamma/W;
//kappa = 3.0*gamma*W/2.0;//beta and kappa are related to surface tension \gamma
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;
din = dout = 1.0;
flux = 0.0;
@ -163,7 +168,8 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
//beta = 12.0*gamma/W;
//kappa = 3.0*gamma*W/2.0;//beta and kappa are related to surface tension \gamma
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)
BoundaryCondition = 0;
@ -173,8 +179,10 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
}
void ScaLBL_FreeLeeModel::SetDomain() {
Dm = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // full domain for analysis
Mask = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // mask domain removes immobile phases
Dm = std::shared_ptr<Domain>(
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
Nx = Dm->Nx;
Ny = Dm->Ny;
@ -188,7 +196,8 @@ void ScaLBL_FreeLeeModel::SetDomain(){
Nzh = Nz + 2;
Nh = Nxh * Nyh * Nzh;
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();
Dm->CommInit();
@ -212,28 +221,30 @@ void ScaLBL_FreeLeeModel::ReadInput(){
std::string first_image = ImageList[IMAGE_INDEX];
Mask->Decomp(first_image);
IMAGE_INDEX++;
}
else if (domain_db->keyExists( "GridFile" )){
} else if (domain_db->keyExists("GridFile")) {
// Read the local domain data
auto input_id = readMicroCT(*domain_db, MPI_COMM_WORLD);
// 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) };
ArraySize size1 = { (size_t) Mask->Nx, (size_t) Mask->Ny, (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<int, 3> size0 = {(int)input_id.size(0), (int)input_id.size(1),
(int)input_id.size(2)};
ArraySize size1 = {(size_t)Mask->Nx, (size_t)Mask->Ny,
(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;
id_view.viewRaw(size1, Mask->id.data());
fill.copy(input_id, 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");
Mask->Decomp(Filename);
}
else{
} else {
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
// Initialize the domain and communication
@ -245,8 +256,10 @@ void ScaLBL_FreeLeeModel::ReadInput(){
int n = k * Nx * Ny + j * Nx + i;
// Initialize the solid phase
signed char label = Mask->id[n];
if (label > 0) id_solid(i,j,k) = 1;
else id_solid(i,j,k) = 0;
if (label > 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);
if (rank == 0) cout << "Domain set." << endl;
if (rank == 0)
cout << "Domain set." << endl;
}
void ScaLBL_FreeLeeModel::Create_TwoFluid() {
@ -273,30 +288,38 @@ void ScaLBL_FreeLeeModel::Create_TwoFluid(){
*/
//.........................................................
// 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();
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)
// 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_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
int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx,Ny,Nz); Map.fill(-2);
if (rank == 0)
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];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,2);
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 2);
comm.barrier();
//...........................................................................
// MAIN VARIABLES ALLOCATED HERE
//...........................................................................
// LBM variables
if (rank==0) printf ("Allocating distributions \n");
if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions.................................
dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int));
@ -313,7 +336,8 @@ void ScaLBL_FreeLeeModel::Create_TwoFluid(){
ScaLBL_AllocateDeviceMemory((void **)&ColorGrad, 3 * sizeof(double) * Np);
//...........................................................................
// 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);
int *TmpMap;
TmpMap = new int[Np];
@ -334,7 +358,8 @@ void ScaLBL_FreeLeeModel::Create_TwoFluid(){
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];
if (n > Nxh * Nyh * Nzh) {
printf("Bad value! idx=%i \n", n);
@ -356,28 +381,35 @@ void ScaLBL_FreeLeeModel::Create_SingleFluid(){
*/
//.........................................................
// 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();
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)
// 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
int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx,Ny,Nz); Map.fill(-2);
if (rank == 0)
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];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1);
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 1);
comm.barrier();
//...........................................................................
// MAIN VARIABLES ALLOCATED HERE
//...........................................................................
// LBM variables
if (rank==0) printf ("Allocating distributions \n");
if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions.................................
dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int));
@ -388,15 +420,15 @@ void ScaLBL_FreeLeeModel::Create_SingleFluid(){
ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np);
//...........................................................................
// 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
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
comm.barrier();
delete[] neighborList;
}
void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
{
void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad() {
double *phase;
phase = new double[Nh];
@ -409,7 +441,8 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
NLABELS = LabelList.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;
@ -418,7 +451,8 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
label_count_global = new double[NLABELS];
// 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 j = 0; j < Nyh; j++) {
for (int i = 0; i < Nxh; i++) {
@ -430,12 +464,18 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
int x = i - 1;
int y = j - 1;
int z = k - 1;
if (x<0) x=0;
if (y<0) y=0;
if (z<0) z=0;
if (x>=Nx) x=Nx-1;
if (y>=Ny) y=Ny-1;
if (z>=Nz) z=Nz-1;
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (z < 0)
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;
VALUE = id[n];
@ -450,15 +490,18 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
}
}
// fluid labels are reserved
if (VALUE == 1) AFFINITY=1.0;
else if (VALUE == 2) AFFINITY=-1.0;
if (VALUE == 1)
AFFINITY = 1.0;
else if (VALUE == 2)
AFFINITY = -1.0;
phase[nh] = AFFINITY;
}
}
}
// 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]);
@ -468,8 +511,11 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
for (unsigned int idx = 0; idx < NLABELS; idx++) {
VALUE = LabelList[idx];
AFFINITY = AffinityList[idx];
double 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);
double 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 ii = 0; ii < 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;
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 j = width; j < Nyh - width; j++) {
for (int i = width; i < Nxh - width; i++) {
@ -549,12 +598,18 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
int idj = j + jj - 1;
int idk = k + kk - 1;
if (idi < 0) idi=0;
if (idj < 0) idj=0;
if (idk < 0) idk=0;
if (!(idi < Nxh)) idi=Nxh-1;
if (!(idj < Nyh)) idj=Nyh-1;
if (!(idk < Nzh)) idk=Nzh-1;
if (idi < 0)
idi = 0;
if (idj < 0)
idj = 0;
if (idk < 0)
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;
double vec_x = double(ii - 1);
@ -565,7 +620,10 @@ void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
phi_x += GWNS * weight * vec_x;
phi_y += GWNS * weight * vec_y;
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;
//compute chemical potential
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
*/
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
if (rank==0) 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 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");
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 (rank == 0)
printf("Initializing density field and distributions for phase-field "
"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) {
//TODO need to revise this function
@ -689,7 +760,8 @@ void ScaLBL_FreeLeeModel::Initialize_TwoFluid(){
if (!(idx < 0) && idx < N)
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];
vb = cDen[Np + n];
value = (va - vb) / (va + vb);
@ -705,7 +777,9 @@ void ScaLBL_FreeLeeModel::Initialize_TwoFluid(){
ScaLBL_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.
//ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, 0, ScaLBL_Comm->LastExterior(), 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
// 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) {
ScaLBL_SetSlice_z(Phi, 1.0, Nx, Ny, Nz, 0);
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
*/
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);
if (Restart == true) {
@ -759,11 +835,15 @@ double ScaLBL_FreeLeeModel::Run_TwoFluid(int returntime){
// Compute the Phase indicator field
// Read for hq happens in this routine (requires communication)
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_Comm->RecvD3Q7AA(hq, 0); //WRITE INTO OPPOSITE
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);
// Perform the collision operation
@ -781,41 +861,52 @@ double ScaLBL_FreeLeeModel::Run_TwoFluid(int returntime){
ScaLBL_Comm_WideHalo->Send(Phi);
//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);
ScaLBL_D3Q19_AAodd_FreeLeeModel_Combined(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_D3Q19_AAodd_FreeLeeModel_Combined(
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->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier();
// Set BCs
if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din,
timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
timestep);
}
if (BoundaryCondition == 4) {
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
}
else if (BoundaryCondition == 5){
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux,
timestep);
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_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);
ScaLBL_D3Q19_AAodd_FreeLeeModel_Combined(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_D3Q19_AAodd_FreeLeeModel_Combined(
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();
// *************EVEN TIMESTEP*************
timestep++;
// Compute the Phase indicator field
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_Comm->RecvD3Q7AA(hq, 0); //WRITE INTO OPPOSITE
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);
// Perform the collision operation
@ -831,28 +922,35 @@ double ScaLBL_FreeLeeModel::Run_TwoFluid(int returntime){
ScaLBL_Comm_WideHalo->Send(Phi);
//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);
ScaLBL_D3Q19_AAeven_FreeLeeModel_Combined(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_D3Q19_AAeven_FreeLeeModel_Combined(
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->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier();
// Set boundary conditions
if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
}
else if (BoundaryCondition == 4){
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
}
else if (BoundaryCondition == 5){
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din,
timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
timestep);
} else if (BoundaryCondition == 4) {
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux,
timestep);
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_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);
ScaLBL_D3Q19_AAeven_FreeLeeModel_Combined(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_D3Q19_AAeven_FreeLeeModel_Combined(
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();
//************************************************************************
PROFILE_STOP("Update");
@ -860,10 +958,13 @@ double ScaLBL_FreeLeeModel::Run_TwoFluid(int returntime){
PROFILE_STOP("Loop");
PROFILE_SAVE("lbpm_color_simulator", 1);
//************************************************************************
if (rank==0) printf("-------------------------------------------------------------------\n");
if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep
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
double MLUPS = double(Np) / cputime / 1000000;
@ -896,54 +997,62 @@ void ScaLBL_FreeLeeModel::Run_SingleFluid(){
//-------------------------------------------------------------------------------------------------------------------
// Perform the collision operation
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->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier();
// Set boundary conditions
// TODO to be revised!
if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din,
timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
timestep);
}
if (BoundaryCondition == 4) {
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
}
else if (BoundaryCondition == 5){
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux,
timestep);
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_D3Q19_AAodd_FreeLeeModel_SingleFluid_BGK(NeighborList, gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz,
0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_D3Q19_AAodd_FreeLeeModel_SingleFluid_BGK(
NeighborList, gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_Comm->Barrier();
// *************EVEN TIMESTEP*************
timestep++;
//-------------------------------------------------------------------------------------------------------------------
// Perform the collision operation
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->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
ScaLBL_Comm->Barrier();
// Set boundary conditions
// TODO to be revised!
if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
}
else if (BoundaryCondition == 4){
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
}
else if (BoundaryCondition == 5){
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din,
timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout,
timestep);
} else if (BoundaryCondition == 4) {
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux,
timestep);
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_D3Q19_AAeven_FreeLeeModel_SingleFluid_BGK(gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz,
0, ScaLBL_Comm->LastExterior(), Np);
ScaLBL_D3Q19_AAeven_FreeLeeModel_SingleFluid_BGK(
gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz, 0,
ScaLBL_Comm->LastExterior(), Np);
ScaLBL_Comm->Barrier();
//************************************************************************
PROFILE_STOP("Update");
@ -951,19 +1060,26 @@ void ScaLBL_FreeLeeModel::Run_SingleFluid(){
PROFILE_STOP("Loop");
PROFILE_SAVE("lbpm_color_simulator", 1);
//************************************************************************
if (rank==0) printf("-------------------------------------------------------------------\n");
if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep;
// Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000;
if (rank==0) printf("********************************************************\n");
if (rank==0) printf("CPU time = %f \n", cputime);
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
if (rank == 0)
printf("CPU time = %f \n", cputime);
if (rank == 0)
printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
MLUPS *= nprocs;
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank==0) printf("********************************************************\n");
if (rank == 0)
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");
fwrite(PhaseField.data(), 8, Nx * Ny * Nz, DIST);
fclose(DIST);
}
ScaLBL_Comm->RegularLayout(Map, Den, PhaseField);
@ -1080,7 +1195,6 @@ void ScaLBL_FreeLeeModel::WriteDebug_TwoFluid(){
CGZ_FILE = fopen(LocalRankFilename, "wb");
fwrite(PhaseField.data(), 8, N, CGZ_FILE);
fclose(CGZ_FILE);
}
void ScaLBL_FreeLeeModel::WriteDebug_SingleFluid() {
@ -1119,30 +1233,38 @@ void ScaLBL_FreeLeeModel::WriteDebug_SingleFluid(){
void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest() {
// 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();
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)
// 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_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
int Npad = (Np / 16 + 2) * 16;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx,Ny,Nz); Map.fill(-2);
if (rank == 0)
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];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1);
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 1);
comm.barrier();
//...........................................................................
// MAIN VARIABLES ALLOCATED HERE
//...........................................................................
// LBM variables
if (rank==0) printf ("Allocating distributions \n");
if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions.................................
dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int));
@ -1159,7 +1281,8 @@ void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest(){
ScaLBL_AllocateDeviceMemory((void **)&ColorGrad, 3 * sizeof(double) * Np);
//...........................................................................
// 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);
int *TmpMap;
TmpMap = new int[Np];
@ -1180,7 +1303,8 @@ void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest(){
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];
if (n > Nxh * Nyh * Nzh) {
printf("Bad value! idx=%i \n", n);
@ -1207,12 +1331,18 @@ void ScaLBL_FreeLeeModel::Create_DummyPhase_MGTest(){
int x = i - 1;
int y = j - 1;
int z = k - 1;
if (x<0) x=0;
if (y<0) y=0;
if (z<0) z=0;
if (x>=Nx) x=Nx-1;
if (y>=Ny) y=Ny-1;
if (z>=Nz) z=Nz-1;
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (z < 0)
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;
phase[nh] = id[n];
}
@ -1231,9 +1361,12 @@ void ScaLBL_FreeLeeModel::MGTest(){
comm.barrier();
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_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
double cgx_loc = 0.0;
@ -1242,8 +1375,10 @@ void ScaLBL_FreeLeeModel::MGTest(){
double cgx, cgy, cgz;
double *ColorGrad_host;
ColorGrad_host = new double[3 * Np];
ScaLBL_CopyToHost(&ColorGrad_host[0],&ColorGrad[0], 3*Np*sizeof(double));
for (int i = ScaLBL_Comm->FirstInterior(); i<ScaLBL_Comm->LastInterior();i++){
ScaLBL_CopyToHost(&ColorGrad_host[0], &ColorGrad[0],
3 * Np * sizeof(double));
for (int i = ScaLBL_Comm->FirstInterior(); i < ScaLBL_Comm->LastInterior();
i++) {
cgx_loc += ColorGrad_host[0 * Np + i];
cgy_loc += ColorGrad_host[1 * Np + i];
cgz_loc += ColorGrad_host[2 * Np + i];

View File

@ -101,6 +101,5 @@ private:
//int rank,nprocs;
void LoadParams(std::shared_ptr<Database> db0);
void AssignComponentLabels_ChemPotential_ColorGrad();
};
#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
*/
class ScaLBL_GreyscaleColorModel {
public:
/**
@ -90,7 +89,8 @@ public:
double Fx, Fy, Fz, flux;
double din, dout, inletA, inletB, outletA, outletB;
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
int Nx, Ny, Nz, N, Np;
@ -161,4 +161,3 @@ private:
*/
double SeedPhaseField(const double seed_water_in_oil);
};

View File

@ -22,23 +22,18 @@
#include <stdlib.h>
#include <time.h>
template<class TYPE>
void DeleteArray( const TYPE *p )
{
delete [] p;
}
template <class TYPE> void DeleteArray(const TYPE *p) { delete[] p; }
ScaLBL_GreyscaleModel::ScaLBL_GreyscaleModel(int RANK, int NP, const Utilities::MPI& 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)
{
ScaLBL_GreyscaleModel::ScaLBL_GreyscaleModel(int RANK, int NP,
const Utilities::MPI &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.fill(0);
}
ScaLBL_GreyscaleModel::~ScaLBL_GreyscaleModel(){
}
ScaLBL_GreyscaleModel::~ScaLBL_GreyscaleModel() {}
void ScaLBL_GreyscaleModel::ReadParams(string filename) {
// read the input database
@ -95,11 +90,11 @@ void ScaLBL_GreyscaleModel::ReadParams(string filename){
if (greyscale_db->keyExists("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") {
CollisionType = 2;
}
else if (collision == "MRT"){
} else if (collision == "MRT") {
CollisionType = 3;
}
// ------------------------------------------------------------------------//
@ -108,16 +103,17 @@ void ScaLBL_GreyscaleModel::ReadParams(string filename){
BoundaryCondition = 0;
if (greyscale_db->keyExists("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");
}
// ------------------------------------------------------------------------//
}
void ScaLBL_GreyscaleModel::SetDomain() {
Dm = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // full domain for analysis
Mask = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // mask domain removes immobile phases
Dm = std::shared_ptr<Domain>(
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
Nx = Dm->Nx;
Ny = Dm->Ny;
@ -135,7 +131,8 @@ void ScaLBL_GreyscaleModel::SetDomain(){
Pressure.resize(Nx, Ny, Nz);
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();
Dm->CommInit();
comm.barrier();
@ -155,12 +152,14 @@ void ScaLBL_GreyscaleModel::ReadInput(){
if (domain_db->keyExists("Filename")) {
auto Filename = domain_db->getScalar<std::string>("Filename");
Mask->Decomp(Filename);
}
else{
if (rank==0) printf("Filename of input image is not found, reading ID.0* instead.");
} else {
if (rank == 0)
printf(
"Filename of input image is not found, reading ID.0* instead.");
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
// Initialize the domain and communication
@ -172,8 +171,10 @@ void ScaLBL_GreyscaleModel::ReadInput(){
int n = k * Nx * Ny + j * Nx + i;
// Initialize the solid phase
signed char label = Mask->id[n];
if (label > 0) id_solid(i,j,k) = 1;
else id_solid(i,j,k) = 0;
if (label > 0)
id_solid(i, j, k) = 1;
else
id_solid(i, j, k) = 0;
}
}
}
@ -187,17 +188,20 @@ void ScaLBL_GreyscaleModel::ReadInput(){
}
}
// 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);
if (rank == 0) cout << "Domain set." << endl;
if (rank == 0)
cout << "Domain set." << endl;
}
/********************************************************
* AssignComponentLabels *
********************************************************/
void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Permeability)
{
void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity,
double *Permeability) {
size_t NLABELS = 0;
signed char VALUE = 0;
double POROSITY = 0.f;
@ -209,7 +213,8 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
NLABELS = LabelList.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
@ -218,7 +223,8 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
label_count = 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 j = 0; j < Ny; j++) {
@ -238,9 +244,9 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
int idx = Map(i, j, k);
if (!(idx < 0)) {
if (POROSITY <= 0.0) {
ERROR("Error: Porosity for grey voxels must be 0.0 < Porosity <= 1.0 !\n");
}
else{
ERROR("Error: Porosity for grey voxels must be 0.0 < "
"Porosity <= 1.0 !\n");
} else {
Porosity[idx] = POROSITY;
}
}
@ -249,7 +255,8 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
}
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 j = 0; j < Ny; j++) {
@ -268,25 +275,29 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
int idx = Map(i, j, k);
if (!(idx < 0)) {
if (PERMEABILITY <= 0.0) {
ERROR("Error: Permeability for grey voxel must be > 0.0 ! \n");
}
else{
Permeability[idx] = PERMEABILITY/Dm->voxel_length/Dm->voxel_length;
ERROR("Error: Permeability for grey voxel must be > "
"0.0 ! \n");
} else {
Permeability[idx] =
PERMEABILITY / Dm->voxel_length / Dm->voxel_length;
}
}
}
}
}
// 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
GreyPorosity = 0.0;
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];
}
@ -297,17 +308,27 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
VALUE = LabelList[idx];
POROSITY = PorosityList[idx];
PERMEABILITY = PermeabilityList[idx];
double volume_fraction = double(label_count_global[idx])/double((Nx-2)*(Ny-2)*(Nz-2)*nprocs);
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);
double volume_fraction =
double(label_count_global[idx]) /
double((Nx - 2) * (Ny - 2) * (Nz - 2) * nprocs);
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;
Porosity_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];
PERMEABILITY = Permeability_host[n];
if (POROSITY <= 0.0) {
ERROR("Error: Porosity for grey voxels must be 0.0 < Porosity <= 1.0 !\n");
}
else if (PERMEABILITY<=0.0){
ERROR("Error: Permeability for grey voxel must be > 0.0 ! \n");
}
else{
ERROR("Error: Porosity for grey voxels must be 0.0 < "
"Porosity <= 1.0 !\n");
} else if (PERMEABILITY <= 0.0) {
ERROR("Error: Permeability for grey voxel must be > "
"0.0 ! \n");
} else {
Porosity[idx] = POROSITY;
Permeability[idx] = PERMEABILITY;
GreyPorosity_loc += POROSITY;
@ -347,11 +368,14 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity,double *Perme
}
}
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) {
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[] Permeability_host;
@ -368,27 +392,34 @@ void ScaLBL_GreyscaleModel::Create(){
//.........................................................
// 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();
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)
// 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;
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
Map.resize(Nx,Ny,Nz); Map.fill(-2);
if (rank == 0)
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];
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1);
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map, neighborList,
Mask->id.data(), Np, 1);
comm.barrier();
//...........................................................................
// MAIN VARIABLES ALLOCATED HERE
//...........................................................................
// LBM variables
if (rank==0) printf ("Allocating distributions \n");
if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions.................................
dist_mem_size = Np * sizeof(double);
neighborSize = 18 * (Np * sizeof(int));
@ -401,7 +432,8 @@ void ScaLBL_GreyscaleModel::Create(){
ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np);
//...........................................................................
// 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);
// copy the neighbor list
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
@ -411,16 +443,17 @@ void ScaLBL_GreyscaleModel::Create(){
Perm = new double[Np];
if (greyscale_db->keyExists("FileVoxelPorosityMap")) {
//NOTE: FileVoxel**Map is a vector, including "file_name, datatype"
auto File_poro = greyscale_db->getVector<std::string>( "FileVoxelPorosityMap" );
auto File_perm = greyscale_db->getVector<std::string>( "FileVoxelPermeabilityMap" );
auto File_poro =
greyscale_db->getVector<std::string>("FileVoxelPorosityMap");
auto File_perm =
greyscale_db->getVector<std::string>("FileVoxelPermeabilityMap");
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
AssignComponentLabels(Poros, Perm);
}
else {
ERROR("Error: PorosityList or FilenameVoxelPorosityMap cannot be found! \n");
} else {
ERROR("Error: PorosityList or FilenameVoxelPorosityMap cannot be "
"found! \n");
}
ScaLBL_CopyToDevice(Porosity, Poros, Np * sizeof(double));
ScaLBL_CopyToDevice(Permeability, Perm, Np * sizeof(double));
@ -428,26 +461,27 @@ void ScaLBL_GreyscaleModel::Create(){
delete[] Perm;
}
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
// 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 (CollisionType == 1) {
ScaLBL_D3Q19_GreyIMRT_Init(fq, Np, Den);
if (rank==0) printf("Collision model: Incompressible MRT.\n");
}
else if (CollisionType==2){
if (rank == 0)
printf("Collision model: Incompressible MRT.\n");
} else if (CollisionType == 2) {
ScaLBL_D3Q19_Init(fq, Np);
if (rank==0) printf("Collision model: BGK.\n");
}
else if (CollisionType==3){
if (rank == 0)
printf("Collision model: BGK.\n");
} else if (CollisionType == 3) {
ScaLBL_D3Q19_Init(fq, Np);
if (rank==0) printf("Collision model: MRT.\n");
}
else{
if (rank==0) printf("Unknown collison type! IMRT collision is used.\n");
if (rank == 0)
printf("Collision model: MRT.\n");
} else {
if (rank == 0)
printf("Unknown collison type! IMRT collision is used.\n");
ScaLBL_D3Q19_GreyIMRT_Init(fq, Np, Den);
CollisionType = 1;
greyscale_db->putScalar<std::string>("collision", "IMRT");
@ -482,14 +516,17 @@ void ScaLBL_GreyscaleModel::Run(){
int nprocs = 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 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")) {
analysis_interval = analysis_db->getScalar<int>("analysis_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")) {
restart_interval = analysis_db->getScalar<int>("restart_interval");
@ -526,16 +563,28 @@ void ScaLBL_GreyscaleModel::Run(){
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
switch (CollisionType) {
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;
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;
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;
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;
}
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
@ -547,35 +596,60 @@ void ScaLBL_GreyscaleModel::Run(){
}
switch (CollisionType) {
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;
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;
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;
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;
}
ScaLBL_DeviceBarrier(); comm.barrier();
ScaLBL_DeviceBarrier();
comm.barrier();
// *************EVEN TIMESTEP*************//
timestep++;
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
switch (CollisionType) {
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;
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;
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;
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;
}
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
@ -587,19 +661,28 @@ void ScaLBL_GreyscaleModel::Run(){
}
switch (CollisionType) {
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;
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;
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;
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;
}
ScaLBL_DeviceBarrier(); comm.barrier();
ScaLBL_DeviceBarrier();
comm.barrier();
//************************************************************************/
if (timestep % analysis_interval == 0) {
@ -620,17 +703,24 @@ void ScaLBL_GreyscaleModel::Run(){
//parameters for domain average
int64_t imin, jmin, kmin, kmax;
// 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
if (BoundaryCondition > 0 && Dm->kproc() == 0) kmin=4;
if (BoundaryCondition > 0 && Dm->kproc() == Dm->nprocz()-1) kmax=Nz-4;
if (BoundaryCondition > 0 && Dm->kproc() == 0)
kmin = 4;
if (BoundaryCondition > 0 && Dm->kproc() == Dm->nprocz() - 1)
kmax = Nz - 4;
imin = jmin = 1;
// If inlet/outlet layers exist use these as default
//if (Dm->inlet_layers_x > 0) imin = Dm->inlet_layers_x;
//if (Dm->inlet_layers_y > 0) jmin = Dm->inlet_layers_y;
if (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->outlet_layers_z > 0 && Dm->kproc() == Dm->nprocz()-1) kmax = Nz-1 - Dm->outlet_layers_z;
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->outlet_layers_z > 0 &&
Dm->kproc() == Dm->nprocz() - 1)
kmax = Nz - 1 - Dm->outlet_layers_z;
vax_loc = vay_loc = vaz_loc = 0.f;
for (int k = kmin; k < kmax; k++) {
@ -698,10 +788,14 @@ void ScaLBL_GreyscaleModel::Run(){
WriteHeader = true;
log_file = fopen("Permeability.csv", "a");
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,
h*h*h*Vs,h*h*As,h*Hs,Xs,vax,vay,vaz, absperm);
fprintf(log_file,
"%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);
}
}
@ -719,12 +813,14 @@ void ScaLBL_GreyscaleModel::Run(){
std::ofstream OutStream("Restart.db");
current_db->print(OutStream, "");
OutStream.close();
}
//Write out Restart data.
std::shared_ptr<double> cfq;
cfq = std::shared_ptr<double>(new double[19*Np],DeleteArray<double>);
ScaLBL_CopyToHost(cfq.get(),fq,19*Np*sizeof(double));// Copy restart data to the CPU
cfq = std::shared_ptr<double>(new double[19 * Np],
DeleteArray<double>);
ScaLBL_CopyToHost(
cfq.get(), fq,
19 * Np * sizeof(double)); // Copy restart data to the CPU
FILE *RESTARTFILE;
RESTARTFILE = fopen(LocalRestartFile, "wb");
@ -739,19 +835,26 @@ void ScaLBL_GreyscaleModel::Run(){
//************************************************************************
ScaLBL_DeviceBarrier();
comm.barrier();
if (rank==0) printf("-------------------------------------------------------------------\n");
if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep;
// Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000;
if (rank==0) printf("********************************************************\n");
if (rank==0) printf("CPU time = %f \n", cputime);
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
if (rank == 0)
printf("CPU time = %f \n", cputime);
if (rank == 0)
printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
MLUPS *= nprocs;
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank==0) printf("********************************************************\n");
if (rank == 0)
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() {
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 VyVar = std::make_shared<IO::Variable>();
@ -771,7 +876,9 @@ void ScaLBL_GreyscaleModel::VelocityField(){
// Create the MeshDataStruct
visData.resize(1);
visData[0].meshName = "domain";
visData[0].mesh = std::make_shared<IO::DomainMesh>( Dm->rank_info,Dm->Nx-2,Dm->Ny-2,Dm->Nz-2,Dm->Lx,Dm->Ly,Dm->Lz );
visData[0].mesh =
std::make_shared<IO::DomainMesh>(Dm->rank_info, Dm->Nx - 2, Dm->Ny - 2,
Dm->Nz - 2, Dm->Lx, Dm->Ly, Dm->Lz);
SignDistVar->name = "SignDist";
SignDistVar->type = IO::VariableType::VolumeVariable;
SignDistVar->dim = 1;
@ -824,7 +931,6 @@ void ScaLBL_GreyscaleModel::VelocityField(){
fillData.copy(Pressure, PressureData);
IO::writeData(timestep, visData, Dm->Comm);
}
void ScaLBL_GreyscaleModel::WriteDebug() {

View File

@ -101,6 +101,7 @@ private:
char LocalRestartFile[40];
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 getIonConcentration(DoubleArray &IonConcentration, const size_t ic);
void getIonConcentration_debug(int timestep);
void getIonFluxDiffusive(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(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 getIonFluxAdvective_debug(int timestep);
void getIonFluxElectrical_debug(int timestep);
@ -63,8 +66,10 @@ public:
vector<double> IonDiffusivity; //User input unit [m^2/sec]
vector<int> IonValence;
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> Cout;//outlet boundary value, can be either concentration [mol/m^3] or flux [mol/m^2/sec]
vector<double>
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> time_conv;
@ -105,7 +110,9 @@ private:
//int rank,nprocs;
void LoadParams(std::shared_ptr<Database> db0);
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 IonFlux_LB_to_Phys(DoubleArray &Den_reg, const size_t ic);
};

View File

@ -20,16 +20,12 @@
#include "models/MRTModel.h"
#include "analysis/distance.h"
#include "common/ReadMicroCT.h"
ScaLBL_MRTModel::ScaLBL_MRTModel(int RANK, int NP, const Utilities::MPI& COMM):
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),
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_MRTModel::~ScaLBL_MRTModel(){
}
ScaLBL_MRTModel::ScaLBL_MRTModel(int RANK, int NP, const Utilities::MPI &COMM)
: 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), 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_MRTModel::~ScaLBL_MRTModel() {}
void ScaLBL_MRTModel::ReadParams(string filename) {
// read the input database
@ -77,16 +73,17 @@ void ScaLBL_MRTModel::ReadParams(string filename){
// Read domain parameters
if (mrt_db->keyExists("BoundaryCondition")) {
BoundaryCondition = mrt_db->getScalar<int>("BC");
}
else if (domain_db->keyExists( "BC" )){
} else if (domain_db->keyExists("BC")) {
BoundaryCondition = domain_db->getScalar<int>("BC");
}
mu = (tau - 0.5) / 3.0;
}
void ScaLBL_MRTModel::SetDomain() {
Dm = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // full domain for analysis
Mask = std::shared_ptr<Domain>(new Domain(domain_db,comm)); // mask domain removes immobile phases
Dm = std::shared_ptr<Domain>(
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
Nx = Dm->Nx;
@ -102,7 +99,8 @@ void ScaLBL_MRTModel::SetDomain(){
Velocity_y.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
comm.barrier();
Dm->CommInit();
@ -120,25 +118,26 @@ void ScaLBL_MRTModel::ReadInput(){
sprintf(LocalRankFilename, "%s%s", "ID.", LocalRankString);
sprintf(LocalRestartFile, "%s%s", "Restart.", LocalRankString);
if (domain_db->keyExists("Filename")) {
auto Filename = domain_db->getScalar<std::string>("Filename");
Mask->Decomp(Filename);
}
else if (domain_db->keyExists( "GridFile" )){
} else if (domain_db->keyExists("GridFile")) {
// Read the local domain data
auto input_id = readMicroCT(*domain_db, comm);
// 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) };
ArraySize size1 = { (size_t) Mask->Nx, (size_t) Mask->Ny, (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<int, 3> size0 = {(int)input_id.size(0), (int)input_id.size(1),
(int)input_id.size(2)};
ArraySize size1 = {(size_t)Mask->Nx, (size_t)Mask->Ny,
(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;
id_view.viewRaw(size1, Mask->id.data());
fill.copy(input_id, id_view);
fill.fill(id_view);
}
else{
} else {
Mask->ReadIDs();
}
@ -151,8 +150,10 @@ void ScaLBL_MRTModel::ReadInput(){
for (int i = 0; i < Nx; i++) {
int n = k * Nx * Ny + j * Nx + i;
// Initialize the solid phase
if (Mask->id[n] > 0) id_solid(i,j,k) = 1;
else id_solid(i,j,k) = 0;
if (Mask->id[n] > 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);
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);
if (rank == 0) cout << "Domain set." << endl;
if (rank == 0)
cout << "Domain set." << endl;
}
void ScaLBL_MRTModel::Create() {
@ -178,27 +182,34 @@ void ScaLBL_MRTModel::Create(){
int rank = Mask->rank();
//.........................................................
// 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();
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)
// 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;
if (rank==0) printf ("Set up memory efficient layout \n");
Map.resize(Nx,Ny,Nz); Map.fill(-2);
if (rank == 0)
printf("Set up memory efficient layout \n");
Map.resize(Nx, Ny, Nz);
Map.fill(-2);
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();
//...........................................................................
// MAIN VARIABLES ALLOCATED HERE
//...........................................................................
// LBM variables
if (rank==0) printf ("Allocating distributions \n");
if (rank == 0)
printf("Allocating distributions \n");
//......................device distributions.................................
int dist_mem_size = Np * sizeof(double);
int neighborSize = 18 * (Np * sizeof(int));
@ -209,7 +220,8 @@ void ScaLBL_MRTModel::Create(){
ScaLBL_AllocateDeviceMemory((void **)&Velocity, 3 * sizeof(double) * Np);
//...........................................................................
// 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
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
comm.barrier();
@ -221,7 +233,8 @@ void ScaLBL_MRTModel::Initialize(){
/*
* This function initializes model
*/
if (rank==0) printf ("Initializing distributions \n");
if (rank == 0)
printf("Initializing distributions \n");
ScaLBL_D3Q19_Init(fq, Np);
}
@ -247,9 +260,12 @@ void ScaLBL_MRTModel::Run(){
}
//.......create and start timer............
ScaLBL_DeviceBarrier(); comm.barrier();
if (rank==0) printf("Beginning AA timesteps, timestepMax = %i \n", timestepMax);
if (rank==0) printf("********************************************************\n");
ScaLBL_DeviceBarrier();
comm.barrier();
if (rank == 0)
printf("Beginning AA timesteps, timestepMax = %i \n", timestepMax);
if (rank == 0)
printf("********************************************************\n");
timestep = 0;
double error = 1.0;
double flow_rate_previous = 0.0;
@ -258,47 +274,54 @@ void ScaLBL_MRTModel::Run(){
//************************************************************************/
timestep++;
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
// Set boundary conditions
if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
}
else if (BoundaryCondition == 4){
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
} else if (BoundaryCondition == 4) {
din =
ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, 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_D3Q19_AAodd_MRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx_setA, rlx_setB, Fx, Fy, Fz);
ScaLBL_DeviceBarrier(); comm.barrier();
ScaLBL_D3Q19_AAodd_MRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(),
Np, rlx_setA, rlx_setB, Fx, Fy, Fz);
ScaLBL_DeviceBarrier();
comm.barrier();
timestep++;
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
// Set boundary conditions
if (BoundaryCondition == 3) {
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep);
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
}
else if (BoundaryCondition == 4){
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
} else if (BoundaryCondition == 4) {
din =
ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, 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_D3Q19_AAeven_MRT(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx_setA, rlx_setB, Fx, Fy, Fz);
ScaLBL_DeviceBarrier(); comm.barrier();
ScaLBL_D3Q19_AAeven_MRT(fq, 0, ScaLBL_Comm->LastExterior(), Np,
rlx_setA, rlx_setB, Fx, Fy, Fz);
ScaLBL_DeviceBarrier();
comm.barrier();
//************************************************************************/
if (timestep % 1000 == 0) {
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[Np], Velocity_y);
ScaLBL_Comm->RegularLayout(Map, &Velocity[2 * Np], Velocity_z);
@ -359,31 +382,41 @@ void ScaLBL_MRTModel::Run(){
Xs = Dm->Comm.sumReduce(Xs);
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) {
printf(" %f\n", absperm);
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,
h*h*h*Vs,h*h*As,h*Hs,Xs,vax,vay,vaz, absperm);
fprintf(log_file,
"%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);
}
}
}
//************************************************************************/
if (rank==0) printf("-------------------------------------------------------------------\n");
if (rank == 0)
printf("---------------------------------------------------------------"
"----\n");
// Compute the walltime per timestep
auto t2 = std::chrono::system_clock::now();
double cputime = std::chrono::duration<double>(t2 - t1).count() / timestep;
// Performance obtained from each node
double MLUPS = double(Np) / cputime / 1000000;
if (rank==0) printf("********************************************************\n");
if (rank==0) printf("CPU time = %f \n", cputime);
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
if (rank == 0)
printf("CPU time = %f \n", cputime);
if (rank == 0)
printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
MLUPS *= nprocs;
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank==0) printf("********************************************************\n");
if (rank == 0)
printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
if (rank == 0)
printf("********************************************************\n");
}
void ScaLBL_MRTModel::VelocityField() {
@ -432,7 +465,9 @@ void ScaLBL_MRTModel::VelocityField(){
if (vis_db->getWithDefault<bool>("write_silo", false)) {
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 VyVar = std::make_shared<IO::Variable>();
@ -443,7 +478,9 @@ void ScaLBL_MRTModel::VelocityField(){
// Create the MeshDataStruct
visData.resize(1);
visData[0].meshName = "domain";
visData[0].mesh = std::make_shared<IO::DomainMesh>( Dm->rank_info,Dm->Nx-2,Dm->Ny-2,Dm->Nz-2,Dm->Lx,Dm->Ly,Dm->Lz );
visData[0].mesh = std::make_shared<IO::DomainMesh>(
Dm->rank_info, Dm->Nx - 2, Dm->Ny - 2, Dm->Nz - 2, Dm->Lx, Dm->Ly,
Dm->Lz);
SignDistVar->name = "SignDist";
SignDistVar->type = IO::VariableType::VolumeVariable;
SignDistVar->dim = 1;

View File

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

View File

@ -1,14 +1,11 @@
#include "models/MultiPhysController.h"
ScaLBL_Multiphys_Controller::ScaLBL_Multiphys_Controller(int RANK, int NP, const Utilities::MPI& 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(
int RANK, int NP, const Utilities::MPI &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() {}
void ScaLBL_Multiphys_Controller::ReadParams(string filename) {
@ -16,7 +13,6 @@ void ScaLBL_Multiphys_Controller::ReadParams(string filename){
db = std::make_shared<Database>(filename);
study_db = db->getDatabase("MultiphysController");
// Default parameters
timestepMax = 10000;
Restart = false;
@ -35,7 +31,8 @@ void ScaLBL_Multiphys_Controller::ReadParams(string filename){
analysis_interval = study_db->getScalar<int>("analysis_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")) {
tolerance = study_db->getScalar<double>("tolerance");
@ -73,71 +70,88 @@ void ScaLBL_Multiphys_Controller::ReadParams(string filename){
if (study_db->keyExists("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
int num_iter_stokes;
vector<double> TimeConv;
TimeConv.assign(IonTimeConv.begin(), IonTimeConv.end());
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);
if (idx_max == 0) {
num_iter_stokes = 2;
}
else{
double temp = 2*TimeConv[idx_max]/StokesTimeConv;//the factor 2 is the number of iterations for the element has max time_conv
} else {
double temp =
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);
}
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
vector<int> num_iter_ion;
vector<double> TimeConv;
TimeConv.assign(IonTimeConv.begin(), IonTimeConv.end());
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);
if (idx_max == 0) {
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));
}
}
else if (idx_max==1){
} else if (idx_max == 1) {
num_iter_ion.push_back(2);
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));
}
}
else if (idx_max==TimeConv.size()-1){
} else if (idx_max == TimeConv.size() - 1) {
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(2);
}
else {
} else {
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(2);
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));
}
}
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
vector<double> TimeConv;

View File

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

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