Merge branch 'master' of github.com:JamesEMcClure/LBPM-WIA

This commit is contained in:
JamesEMcclure 2020-09-16 11:28:13 -04:00
commit 64f1bfd37d
26 changed files with 9709 additions and 461 deletions

View File

@ -73,9 +73,9 @@ void Minkowski::ComputeScalar(const DoubleArray& Field, const double isovalue)
//int Nx = Field.size(0); //int Nx = Field.size(0);
//int Ny = Field.size(1); //int Ny = Field.size(1);
//int Nz = Field.size(2); //int Nz = Field.size(2);
for (int k=0; k<Nz-1; k++){ for (int k=1; k<Nz-1; k++){
for (int j=0; j<Ny-1; j++){ for (int j=1; j<Ny-1; j++){
for (int i=0; i<Nx-1; i++){ for (int i=1; i<Nx-1; i++){
object.LocalIsosurface(Field,isovalue,i,j,k); object.LocalIsosurface(Field,isovalue,i,j,k);
for (int idx=0; idx<object.TriangleCount; idx++){ for (int idx=0; idx<object.TriangleCount; idx++){
e1 = object.Face(idx); e1 = object.Face(idx);
@ -106,7 +106,21 @@ void Minkowski::ComputeScalar(const DoubleArray& Field, const double isovalue)
Xi -= 0.5; Xi -= 0.5;
} }
// Euler characteristic -- each vertex shared by four cubes // Euler characteristic -- each vertex shared by four cubes
Xi += 0.25*double(object.VertexCount); //Xi += 0.25*double(object.VertexCount);
// check if vertices are at corners
for (int idx=0; idx<object.VertexCount; idx++){
/*auto P1 = object.vertex.coords(idx);
if ( remainder(P1.x,1.0)==0.0 && remainder(P1.y,1.0)==0.0 && remainder(P1.z,1.0)==0.0 ){
Xi += 0.125;
}
else
*/
Xi += 0.25;
}
/*double nside_extern = double(npts);
double nside_intern = double(npts)-3.0;
EulerChar=0.0;
if (npts > 0) EulerChar = (0.25*nvert - nside_intern - 0.5*nside_extern + nface); */
} }
} }
} }
@ -143,7 +157,7 @@ void Minkowski::MeasureObject(){
* 0 - labels the object * 0 - labels the object
* 1 - labels the rest of the * 1 - labels the rest of the
*/ */
//DoubleArray smooth_distance(Nx,Ny,Nz);
for (int k=0; k<Nz; k++){ for (int k=0; k<Nz; k++){
for (int j=0; j<Ny; j++){ for (int j=0; j<Ny; j++){
for (int i=0; i<Nx; i++){ for (int i=0; i<Nx; i++){
@ -152,6 +166,44 @@ void Minkowski::MeasureObject(){
} }
} }
CalcDist(distance,id,*Dm); CalcDist(distance,id,*Dm);
//Mean3D(distance,smooth_distance);
//Eikonal(distance, id, *Dm, 20, {true, true, true});
ComputeScalar(distance,0.0);
}
void Minkowski::MeasureObject(double factor, const DoubleArray &Phi){
/*
* compute the distance to an object
*
* THIS ALGORITHM ASSUMES THAT id() is populated with phase id to distinguish objects
* 0 - labels the object
* 1 - labels the rest of the
*/
for (int k=0; k<Nz; k++){
for (int j=0; j<Ny; j++){
for (int i=0; i<Nx; i++){
distance(i,j,k) =2.0*double(id(i,j,k))-1.0;
}
}
}
CalcDist(distance,id,*Dm);
for (int k=0; k<Nz; k++){
for (int j=0; j<Ny; j++){
for (int i=0; i<Nx; i++){
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));
if (dist_value*new_distance < 0.0 )
new_distance = (-1.0)*new_distance;
distance(i,j,k) = new_distance;
}
}
}
}
ComputeScalar(distance,0.0); ComputeScalar(distance,0.0);
} }
@ -201,6 +253,50 @@ int Minkowski::MeasureConnectedPathway(){
return n_connected_components; return n_connected_components;
} }
int Minkowski::MeasureConnectedPathway(double factor, const DoubleArray &Phi){
/*
* compute the connected pathway for object with LABEL in id field
* compute the labels for connected components
* compute the distance to the connected pathway
*
* THIS ALGORITHM ASSUMES THAT id() is populated with phase id to distinguish objects
*/
char LABEL = 0;
for (int k=0; k<Nz; k++){
for (int j=0; j<Ny; j++){
for (int i=0; i<Nx; i++){
if (id(i,j,k) == LABEL){
distance(i,j,k) = 1.0;
}
else
distance(i,j,k) = -1.0;
}
}
}
// 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);
// int n_connected_components = ComputeGlobalPhaseComponent(Nx-2,Ny-2,Nz-2,Dm->rank_info,const IntArray &PhaseID, int &VALUE, BlobIDArray &GlobalBlobID, Dm->Comm )
MPI_Barrier(Dm->Comm);
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{
id(i,j,k) = 1;
}
}
}
}
MeasureObject(factor,Phi);
return n_connected_components;
}
void Minkowski::PrintAll() void Minkowski::PrintAll()
{ {

View File

@ -25,6 +25,7 @@
#include "common/Communication.h" #include "common/Communication.h"
#include "analysis/analysis.h" #include "analysis/analysis.h"
#include "analysis/distance.h" #include "analysis/distance.h"
#include "analysis/filters.h"
#include "common/Utilities.h" #include "common/Utilities.h"
#include "common/MPI_Helpers.h" #include "common/MPI_Helpers.h"
@ -77,7 +78,9 @@ public:
Minkowski(std::shared_ptr <Domain> Dm); Minkowski(std::shared_ptr <Domain> Dm);
~Minkowski(); ~Minkowski();
void MeasureObject(); void MeasureObject();
void MeasureObject(double factor, const DoubleArray &Phi);
int MeasureConnectedPathway(); int MeasureConnectedPathway();
int MeasureConnectedPathway(double factor, const DoubleArray &Phi);
void ComputeScalar(const DoubleArray& Field, const double isovalue); void ComputeScalar(const DoubleArray& Field, const double isovalue);
void PrintAll(); void PrintAll();

View File

@ -427,13 +427,13 @@ void SubPhase::Full(){
} }
} }
// measure the whole object // measure the whole object
morph_n->MeasureObject(); morph_n->MeasureObject();//0.5/beta,Phi);
nd.V = morph_n->V(); nd.V = morph_n->V();
nd.A = morph_n->A(); nd.A = morph_n->A();
nd.H = morph_n->H(); nd.H = morph_n->H();
nd.X = morph_n->X(); nd.X = morph_n->X();
// measure only the connected part // measure only the connected part
nd.Nc = morph_n->MeasureConnectedPathway(); nd.Nc = morph_n->MeasureConnectedPathway();//0.5/beta,Phi);
nc.V = morph_n->V(); nc.V = morph_n->V();
nc.A = morph_n->A(); nc.A = morph_n->A();
nc.H = morph_n->H(); nc.H = morph_n->H();
@ -475,13 +475,13 @@ void SubPhase::Full(){
} }
} }
} }
morph_w->MeasureObject(); morph_w->MeasureObject();//-0.5/beta,Phi);
wd.V = morph_w->V(); wd.V = morph_w->V();
wd.A = morph_w->A(); wd.A = morph_w->A();
wd.H = morph_w->H(); wd.H = morph_w->H();
wd.X = morph_w->X(); wd.X = morph_w->X();
// measure only the connected part // measure only the connected part
wd.Nc = morph_w->MeasureConnectedPathway(); wd.Nc = morph_w->MeasureConnectedPathway();//-0.5/beta,Phi);
wc.V = morph_w->V(); wc.V = morph_w->V();
wc.A = morph_w->A(); wc.A = morph_w->A();
wc.H = morph_w->H(); wc.H = morph_w->H();

View File

@ -1,7 +1,5 @@
#include "analysis/dcel.h" #include "analysis/dcel.h"
DECL::DECL(){ DECL::DECL(){
} }
@ -15,6 +13,25 @@ int DECL::Face(int index){
return FaceData[index]; return FaceData[index];
} }
void DECL::Write(){
int e1,e2,e3;
FILE *TRIANGLES;
TRIANGLES = fopen("triangles.stl","w");
fprintf(TRIANGLES,"solid \n");
for (int idx=0; idx<TriangleCount; idx++){
e1 = Face(idx);
e2 = halfedge.next(e1);
e3 = halfedge.next(e2);
auto P1 = vertex.coords(halfedge.v1(e1));
auto P2 = vertex.coords(halfedge.v1(e2));
auto P3 = vertex.coords(halfedge.v1(e3));
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);
}
fclose(TRIANGLES);
}
void DECL::LocalIsosurface(const DoubleArray& A, double value, const int i, const int j, const int k){ void DECL::LocalIsosurface(const DoubleArray& A, double value, const int i, const int j, const int k){
Point P,Q; Point P,Q;
Point PlaceHolder; Point PlaceHolder;
@ -350,243 +367,43 @@ double DECL::EdgeAngle(int edge)
return angle; return angle;
} }
void Isosurface(DoubleArray &A, const double &v) void iso_surface(const Array<double>&Field, const double isovalue)
{ {
NULL_USE( v ); DECL object;
int e1,e2,e3;
Point P,Q; FILE *TRIANGLES;
Point PlaceHolder; TRIANGLES = fopen("isosurface.stl","w");
Point C0,C1,C2,C3,C4,C5,C6,C7; fprintf(TRIANGLES,"solid isosurface\n");
int Nx = Field.size(0);
int TriangleCount; int Ny = Field.size(1);
int VertexCount; int Nz = Field.size(2);
int CubeIndex;
Point VertexList[12];
Point NewVertexList[12];
int LocalRemap[12];
Point cellvertices[20];
std::array<std::array<int,3>,20> Triangles;
Triangles.fill( { 0 } );
// Values from array 'A' at the cube corners
double CubeValues[8];
int Nx = A.size(0);
int Ny = A.size(1);
int Nz = A.size(2);
// 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;
std::vector<std::array<int,6>> HalfEdge;
for (int k=1; k<Nz-1; k++){ for (int k=1; k<Nz-1; k++){
for (int j=1; j<Ny-1; j++){ for (int j=1; j<Ny-1; j++){
for (int i=1; i<Nx-1; i++){ for (int i=1; i<Nx-1; i++){
// Set the corner values for this cube object.LocalIsosurface(Field,isovalue,i,j,k);
CubeValues[0] = A(i,j,k); for (int idx=0; idx<object.TriangleCount; idx++){
CubeValues[1] = A(i+1,j,k); e1 = object.Face(idx);
CubeValues[2] = A(i+1,j+1,k); e2 = object.halfedge.next(e1);
CubeValues[3] = A(i,j+1,k); e3 = object.halfedge.next(e2);
CubeValues[4] = A(i,j,k+1); auto P1 = object.vertex.coords(object.halfedge.v1(e1));
CubeValues[5] = A(i+1,j,k+1); auto P2 = object.vertex.coords(object.halfedge.v1(e2));
CubeValues[6] = A(i+1,j+1,k+1); auto P3 = object.vertex.coords(object.halfedge.v1(e3));
CubeValues[7] = A(i,j+1,k+1); auto Normal = object.TriNormal(e1);
// P1.x += 1.0*i; P1.y += 1.0*j; P1.z +=1.0*k;
//Determine the index into the edge table which //P2.x += 1.0*i; P2.y += 1.0*j; P2.z +=1.0*k;
//tells us which vertices are inside of the surface //P3.x += 1.0*i; P3.y += 1.0*j; P3.z +=1.0*k;
CubeIndex = 0; fprintf(TRIANGLES,"facet normal %f %f %f\n",Normal.x,Normal.y,Normal.z);
if (CubeValues[0] < 0.0f) CubeIndex |= 1; fprintf(TRIANGLES," outer loop\n");
if (CubeValues[1] < 0.0f) CubeIndex |= 2; fprintf(TRIANGLES," vertex %f %f %f\n",P1.x,P1.y,P1.z);
if (CubeValues[2] < 0.0f) CubeIndex |= 4; fprintf(TRIANGLES," vertex %f %f %f\n",P2.x,P2.y,P2.z);
if (CubeValues[3] < 0.0f) CubeIndex |= 8; fprintf(TRIANGLES," vertex %f %f %f\n",P3.x,P3.y,P3.z);
if (CubeValues[4] < 0.0f) CubeIndex |= 16; fprintf(TRIANGLES," endloop\n");
if (CubeValues[5] < 0.0f) CubeIndex |= 32; fprintf(TRIANGLES,"endfacet\n");
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){
P = VertexInterp(C0,C1,CubeValues[0],CubeValues[1]);
VertexList[0] = P;
Q = C0;
}
if (edgeTable[CubeIndex] & 2){
P = VertexInterp(C1,C2,CubeValues[1],CubeValues[2]);
VertexList[1] = P;
Q = C1;
}
if (edgeTable[CubeIndex] & 4){
P = VertexInterp(C2,C3,CubeValues[2],CubeValues[3]);
VertexList[2] = P;
Q = C2;
}
if (edgeTable[CubeIndex] & 8){
P = VertexInterp(C3,C0,CubeValues[3],CubeValues[0]);
VertexList[3] = P;
Q = C3;
}
if (edgeTable[CubeIndex] & 16){
P = VertexInterp(C4,C5,CubeValues[4],CubeValues[5]);
VertexList[4] = P;
Q = C4;
}
if (edgeTable[CubeIndex] & 32){
P = VertexInterp(C5,C6,CubeValues[5],CubeValues[6]);
VertexList[5] = P;
Q = C5;
}
if (edgeTable[CubeIndex] & 64){
P = VertexInterp(C6,C7,CubeValues[6],CubeValues[7]);
VertexList[6] = P;
Q = C6;
}
if (edgeTable[CubeIndex] & 128){
P = VertexInterp(C7,C4,CubeValues[7],CubeValues[4]);
VertexList[7] = P;
Q = C7;
}
if (edgeTable[CubeIndex] & 256){
P = VertexInterp(C0,C4,CubeValues[0],CubeValues[4]);
VertexList[8] = P;
Q = C0;
}
if (edgeTable[CubeIndex] & 512){
P = VertexInterp(C1,C5,CubeValues[1],CubeValues[5]);
VertexList[9] = P;
Q = C1;
}
if (edgeTable[CubeIndex] & 1024){
P = VertexInterp(C2,C6,CubeValues[2],CubeValues[6]);
VertexList[10] = P;
Q = C2;
}
if (edgeTable[CubeIndex] & 2048){
P = VertexInterp(C3,C7,CubeValues[3],CubeValues[7]);
VertexList[11] = P;
Q = C3;
}
VertexCount=0;
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)
{
NewVertexList[VertexCount] = VertexList[triTable[CubeIndex][idx]];
LocalRemap[triTable[CubeIndex][idx]] = VertexCount;
VertexCount++;
}
}
for (int idx=0;idx<VertexCount;idx++) {
P = NewVertexList[idx];
//P.x += i;
//P.y += j;
//P.z += k;
cellvertices[idx] = P;
}
TriangleCount = 0;
for (int idx=0;triTable[CubeIndex][idx]!=-1;idx+=3) {
Triangles[TriangleCount][0] = LocalRemap[triTable[CubeIndex][idx+0]];
Triangles[TriangleCount][1] = LocalRemap[triTable[CubeIndex][idx+1]];
Triangles[TriangleCount][2] = LocalRemap[triTable[CubeIndex][idx+2]];
TriangleCount++;
}
int nTris = TriangleCount;
// Now add the local values to the DECL data structure
HalfEdge.resize(nTris*3);
int idx_edge=0;
for (int idx=0; idx<TriangleCount; idx++){
int V1 = Triangles[idx][0];
int V2 = Triangles[idx][1];
int V3 = Triangles[idx][2];
// first edge: V1->V2
HalfEdge[idx_edge][0] = V1; // first vertex
HalfEdge[idx_edge][1] = V2; // second vertex
HalfEdge[idx_edge][2] = idx; // triangle
HalfEdge[idx_edge][3] = -1; // twin
HalfEdge[idx_edge][4] = idx_edge+2; // previous edge
HalfEdge[idx_edge][5] = idx_edge+1; // next edge
idx_edge++;
// second edge: V2->V3
HalfEdge[idx_edge][0] = V2; // first vertex
HalfEdge[idx_edge][1] = V3; // second vertex
HalfEdge[idx_edge][2] = idx; // triangle
HalfEdge[idx_edge][3] = -1; // twin
HalfEdge[idx_edge][4] = idx_edge-1; // previous edge
HalfEdge[idx_edge][5] = idx_edge+1; // next edge
idx_edge++;
// third edge: V3->V1
HalfEdge[idx_edge][0] = V3; // first vertex
HalfEdge[idx_edge][1] = V1; // second vertex
HalfEdge[idx_edge][2] = idx; // triangle
HalfEdge[idx_edge][3] = -1; // twin
HalfEdge[idx_edge][4] = idx_edge-1; // previous edge
HalfEdge[idx_edge][5] = idx_edge-2; // next edge
idx_edge++;
}
int EdgeCount=idx_edge;
for (int idx=0; idx<EdgeCount; idx++){
int V1=HalfEdge[idx][0];
int V2=HalfEdge[idx][1];
// Find all the twins within the cube
for (int jdx=0; idx<EdgeCount; jdx++){
if (HalfEdge[jdx][1] == V1 && HalfEdge[jdx][0] == V2){
// this is the pair
HalfEdge[idx][3] = jdx;
HalfEdge[jdx][3] = idx;
}
if (HalfEdge[jdx][1] == V2 && HalfEdge[jdx][0] == 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[idx_edge][3] = -1; // ghost twin for x=0 face
if (P.x == 1.0 && Q.x == 1.0) HalfEdge[idx_edge][3] = -2; // ghost twin for x=1 face
if (P.y == 0.0 && Q.y == 0.0) HalfEdge[idx_edge][3] = -3; // ghost twin for y=0 face
if (P.y == 1.0 && Q.y == 1.0) HalfEdge[idx_edge][3] = -4; // ghost twin for y=1 face
if (P.z == 0.0 && Q.z == 0.0) HalfEdge[idx_edge][3] = -5; // ghost twin for z=0 face
if (P.z == 1.0 && Q.z == 1.0) HalfEdge[idx_edge][3] = -6; // ghost twin for z=1 face
}
// Find all the angles
/*for (int idx=0; idx<EdgeCount; idx++){
int V1=HalfEdge[idx][0];
int V2=HalfEdge[idx][1];
int T1= HalfEdge[idx_edge][2];
int twin=HalfEdge[idx_edge][3];
if (twin == -1){
} }
}*/
// Map vertices to global coordinates
for (int idx=0;idx<VertexCount;idx++) {
P = cellvertices[idx];
P.x += i;
P.y += j;
P.z += k;
cellvertices[idx] = P;
} }
} }
} }
fprintf(TRIANGLES,"endsolid isosurface\n");
fclose(TRIANGLES);
} }
}

View File

@ -1,3 +1,6 @@
#ifndef DCEL_INC
#define DCEL_INC
#include <vector> #include <vector>
#include "analysis/pmmc.h" #include "analysis/pmmc.h"
@ -67,6 +70,7 @@ public:
Vertex vertex; Vertex vertex;
Halfedge halfedge; Halfedge halfedge;
void LocalIsosurface(const DoubleArray& A, double value, int i, int j, int k); void LocalIsosurface(const DoubleArray& A, double value, int i, int j, int k);
void Write();
int Face(int index); int Face(int index);
double origin(int edge); double origin(int edge);
@ -78,3 +82,7 @@ public:
private: private:
std::vector<int> FaceData; std::vector<int> FaceData;
}; };
void iso_surface(const Array<double>&Field, const double isovalue);
#endif

View File

@ -197,6 +197,148 @@ void CalcVecDist( Array<Vec> &d, const Array<int> &ID0, const Domain &Dm,
} }
} }
double Eikonal(DoubleArray &Distance, const Array<char> &ID, Domain &Dm, int timesteps, const std::array<bool,3>& periodic){
/*
* This routine converts the data in the Distance array to a signed distance
* by solving the equation df/dt = sign(1-|grad f|), where Distance provides
* the values of f on the mesh associated with domain Dm
* It has been tested with segmented data initialized to values [-1,1]
* and will converge toward the signed distance to the surface bounding the associated phases
*
* Reference:
* Min C (2010) On reinitializing level set functions, Journal of Computational Physics229
*/
int i,j,k;
double dt=0.1;
double Dx,Dy,Dz;
double Dxp,Dxm,Dyp,Dym,Dzp,Dzm;
double Dxxp,Dxxm,Dyyp,Dyym,Dzzp,Dzzm;
double sign,norm;
double LocalVar,GlobalVar,LocalMax,GlobalMax;
int xdim,ydim,zdim;
xdim=Dm.Nx-2;
ydim=Dm.Ny-2;
zdim=Dm.Nz-2;
//fillHalo<double> fillData(Dm.Comm, Dm.rank_info,xdim,ydim,zdim,1,1,1,0,1);
fillHalo<double> fillData( Dm.Comm, Dm.rank_info, {xdim, ydim, zdim}, {1,1,1}, 50, 1, {true,true,true}, periodic );
// Arrays to store the second derivatives
DoubleArray Dxx(Dm.Nx,Dm.Ny,Dm.Nz);
DoubleArray Dyy(Dm.Nx,Dm.Ny,Dm.Nz);
DoubleArray Dzz(Dm.Nx,Dm.Ny,Dm.Nz);
int count = 0;
while (count < timesteps){
// Communicate the halo of values
fillData.fill(Distance);
// Compute second order derivatives
for (k=1;k<Dm.Nz-1;k++){
for (j=1;j<Dm.Ny-1;j++){
for (i=1;i<Dm.Nx-1;i++){
Dxx(i,j,k) = Distance(i+1,j,k) + Distance(i-1,j,k) - 2*Distance(i,j,k);
Dyy(i,j,k) = Distance(i,j+1,k) + Distance(i,j-1,k) - 2*Distance(i,j,k);
Dzz(i,j,k) = Distance(i,j,k+1) + Distance(i,j,k-1) - 2*Distance(i,j,k);
}
}
}
fillData.fill(Dxx);
fillData.fill(Dyy);
fillData.fill(Dzz);
LocalMax=LocalVar=0.0;
// Execute the next timestep
for (k=1;k<Dm.Nz-1;k++){
for (j=1;j<Dm.Ny-1;j++){
for (i=1;i<Dm.Nx-1;i++){
int n = k*Dm.Nx*Dm.Ny + j*Dm.Nx + i;
sign = -1;
if (ID(i,j,k) == 1) sign = 1;
// local second derivative terms
Dxxp = minmod(Dxx(i,j,k),Dxx(i+1,j,k));
Dyyp = minmod(Dyy(i,j,k),Dyy(i,j+1,k));
Dzzp = minmod(Dzz(i,j,k),Dzz(i,j,k+1));
Dxxm = minmod(Dxx(i,j,k),Dxx(i-1,j,k));
Dyym = minmod(Dyy(i,j,k),Dyy(i,j-1,k));
Dzzm = minmod(Dzz(i,j,k),Dzz(i,j,k-1));
/* //............Compute upwind derivatives ...................
Dxp = Distance(i+1,j,k) - Distance(i,j,k) + 0.5*Dxxp;
Dyp = Distance(i,j+1,k) - Distance(i,j,k) + 0.5*Dyyp;
Dzp = Distance(i,j,k+1) - Distance(i,j,k) + 0.5*Dzzp;
Dxm = Distance(i,j,k) - Distance(i-1,j,k) + 0.5*Dxxm;
Dym = Distance(i,j,k) - Distance(i,j-1,k) + 0.5*Dyym;
Dzm = Distance(i,j,k) - Distance(i,j,k-1) + 0.5*Dzzm;
*/
Dxp = Distance(i+1,j,k)- Distance(i,j,k) - 0.5*Dxxp;
Dyp = Distance(i,j+1,k)- Distance(i,j,k) - 0.5*Dyyp;
Dzp = Distance(i,j,k+1)- Distance(i,j,k) - 0.5*Dzzp;
Dxm = Distance(i,j,k) - Distance(i-1,j,k) + 0.5*Dxxm;
Dym = Distance(i,j,k) - Distance(i,j-1,k) + 0.5*Dyym;
Dzm = Distance(i,j,k) - Distance(i,j,k-1) + 0.5*Dzzm;
// Compute upwind derivatives for Godunov Hamiltonian
if (sign < 0.0){
if (Dxp + Dxm > 0.f) Dx = Dxp*Dxp;
else Dx = Dxm*Dxm;
if (Dyp + Dym > 0.f) Dy = Dyp*Dyp;
else Dy = Dym*Dym;
if (Dzp + Dzm > 0.f) Dz = Dzp*Dzp;
else Dz = Dzm*Dzm;
}
else{
if (Dxp + Dxm < 0.f) Dx = Dxp*Dxp;
else Dx = Dxm*Dxm;
if (Dyp + Dym < 0.f) Dy = Dyp*Dyp;
else Dy = Dym*Dym;
if (Dzp + Dzm < 0.f) Dz = Dzp*Dzp;
else Dz = Dzm*Dzm;
}
//Dx = max(Dxp*Dxp,Dxm*Dxm);
//Dy = max(Dyp*Dyp,Dym*Dym);
//Dz = max(Dzp*Dzp,Dzm*Dzm);
norm=sqrt(Dx + Dy + Dz);
if (norm > 1.0) norm=1.0;
Distance(i,j,k) += dt*sign*(1.0 - norm);
LocalVar += dt*sign*(1.0 - norm);
if (fabs(dt*sign*(1.0 - norm)) > LocalMax)
LocalMax = fabs(dt*sign*(1.0 - norm));
}
}
}
MPI_Allreduce(&LocalVar,&GlobalVar,1,MPI_DOUBLE,MPI_SUM,Dm.Comm);
MPI_Allreduce(&LocalMax,&GlobalMax,1,MPI_DOUBLE,MPI_MAX,Dm.Comm);
GlobalVar /= Dm.Volume;
count++;
if (count%50 == 0 && Dm.rank()==0 )
printf("Time=%i, Max variation=%f, Global variation=%f \n",count,GlobalMax,GlobalVar);
if (fabs(GlobalMax) < 1e-5){
if (Dm.rank()==0) printf("Exiting with max tolerance of 1e-5 \n");
count=timesteps;
}
}
return GlobalVar;
}
// Explicit instantiations // Explicit instantiations
template void CalcDist<float>( Array<float>&, const Array<char>&, const Domain&, const std::array<bool,3>&, const std::array<double,3>& ); template void CalcDist<float>( Array<float>&, const Array<char>&, const Domain&, const std::array<bool,3>&, const std::array<double,3>& );

View File

@ -31,6 +31,16 @@ struct Vec {
}; };
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; }
inline double minmod(double &a, double &b){
double value;
value = a;
if ( a*b < 0.0) value=0.0;
else if (fabs(a) > fabs(b)) value = b;
return value;
}
/*! /*!
* @brief Calculate the distance using a simple method * @brief Calculate the distance using a simple method
@ -55,4 +65,16 @@ void CalcDist( Array<TYPE> &Distance, const Array<char> &ID, const Domain &Dm,
void CalcVecDist( Array<Vec> &Distance, const Array<int> &ID, const Domain &Dm, void CalcVecDist( Array<Vec> &Distance, const Array<int> &ID, const Domain &Dm,
const std::array<bool,3>& periodic = {true,true,true}, const std::array<double,3>& dx = {1,1,1} ); const std::array<bool,3>& periodic = {true,true,true}, const std::array<double,3>& dx = {1,1,1} );
/*!
* @brief Calculate the distance based on solution of Eikonal equation
* @details This routine calculates the signed distance to the nearest domain surface.
* @param[out] Distance Distance function
* @param[in] ID Domain id
* @param[in] Dm Domain information
* @param[in] timesteps number of timesteps to run for Eikonal solver
* @param[in] periodic Directions that are periodic
*/
double Eikonal(DoubleArray &Distance, const Array<char> &ID, Domain &Dm, int timesteps, const std::array<bool,3>& periodic);
#endif #endif

View File

@ -17,6 +17,33 @@
#include "math.h" #include "math.h"
#include "ProfilerApp.h" #include "ProfilerApp.h"
void Mean3D( const Array<double> &Input, Array<double> &Output )
{
PROFILE_START("Mean3D");
// Perform a 3D Mean filter on Input array
int i,j,k;
int Nx = int(Input.size(0));
int Ny = int(Input.size(1));
int Nz = int(Input.size(2));
for (k=1; k<Nz-1; k++){
for (j=1; j<Ny-1; j++){
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);
Output(i,j,k) = MeanValue/27.0;
}
}
}
PROFILE_STOP("Mean3D");
}
void Med3D( const Array<float> &Input, Array<float> &Output ) void Med3D( const Array<float> &Input, Array<float> &Output )
{ {

View File

@ -19,6 +19,13 @@
#include "common/Array.h" #include "common/Array.h"
/*!
* @brief Filter image
* @details This routine performs a mean filter
* @param[in] Input Input image
* @param[out] Output Output image
*/
void Mean3D( const Array<double> &Input, Array<double> &Output );
/*! /*!
* @brief Filter image * @brief Filter image
@ -28,7 +35,6 @@
*/ */
void Med3D( const Array<float> &Input, Array<float> &Output ); void Med3D( const Array<float> &Input, Array<float> &Output );
/*! /*!
* @brief Filter image * @brief Filter image
* @details This routine performs a non-linear local means filter * @details This routine performs a non-linear local means filter

View File

@ -710,7 +710,7 @@ void Domain::AggregateLabels( const std::string& filename ){
int full_ny = npy*(ny-2); int full_ny = npy*(ny-2);
int full_nz = npz*(nz-2); int full_nz = npz*(nz-2);
int local_size = (nx-2)*(ny-2)*(nz-2); int local_size = (nx-2)*(ny-2)*(nz-2);
long int full_size = long(full_nx)*long(full_ny)*long(full_nz); unsigned long int full_size = long(full_nx)*long(full_ny)*long(full_nz);
signed char *LocalID; signed char *LocalID;
LocalID = new signed char [local_size]; LocalID = new signed char [local_size];
@ -740,7 +740,7 @@ void Domain::AggregateLabels( const std::string& filename ){
int y = j-1; int y = j-1;
int z = k-1; int z = k-1;
int n_local = (k-1)*(nx-2)*(ny-2) + (j-1)*(nx-2) + i-1; int n_local = (k-1)*(nx-2)*(ny-2) + (j-1)*(nx-2) + i-1;
int n_full = z*full_nx*full_ny + y*full_nx + x; unsigned long int n_full = z*long(full_nx)*long(full_ny) + y*long(full_nx) + x;
FullID[n_full] = LocalID[n_local]; FullID[n_full] = LocalID[n_local];
} }
} }
@ -760,7 +760,7 @@ void Domain::AggregateLabels( const std::string& filename ){
int y = j-1 + ipy*(ny-2); int y = j-1 + ipy*(ny-2);
int z = k-1 + ipz*(nz-2); int z = k-1 + ipz*(nz-2);
int n_local = (k-1)*(nx-2)*(ny-2) + (j-1)*(nx-2) + i-1; int n_local = (k-1)*(nx-2)*(ny-2) + (j-1)*(nx-2) + i-1;
int n_full = z*full_nx*full_ny + y*full_nx + x; unsigned long int n_full = z*long(full_nx)*long(full_ny) + y*long(full_nx) + x;
FullID[n_full] = LocalID[n_local]; FullID[n_full] = LocalID[n_local];
} }
} }

View File

@ -95,43 +95,43 @@ ScaLBL_Communicator::ScaLBL_Communicator(std::shared_ptr <Domain> Dm){
BoundaryCondition = Dm->BoundaryCondition; BoundaryCondition = Dm->BoundaryCondition;
//...................................................................................... //......................................................................................
ScaLBL_AllocateZeroCopy((void **) &sendbuf_x, 5*sendCount_x*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_x, 2*5*sendCount_x*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_X, 5*sendCount_X*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_X, 2*5*sendCount_X*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_y, 5*sendCount_y*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_y, 2*5*sendCount_y*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Y, 5*sendCount_Y*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_Y, 2*5*sendCount_Y*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_z, 5*sendCount_z*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_z, 2*5*sendCount_z*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Z, 5*sendCount_Z*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_Z, 2*5*sendCount_Z*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xy, sendCount_xy*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_xy, 2*sendCount_xy*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xY, sendCount_xY*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_xY, 2*sendCount_xY*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xy, sendCount_Xy*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xy, 2*sendCount_Xy*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XY, sendCount_XY*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_XY, 2*sendCount_XY*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xz, sendCount_xz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_xz, 2*sendCount_xz*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_xZ, sendCount_xZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_xZ, 2*sendCount_xZ*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xz, sendCount_Xz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_Xz, 2*sendCount_Xz*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_XZ, sendCount_XZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_XZ, 2*sendCount_XZ*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_yz, sendCount_yz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_yz, 2*sendCount_yz*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_yZ, sendCount_yZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_yZ, 2*sendCount_yZ*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_Yz, sendCount_Yz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_Yz, 2*sendCount_Yz*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &sendbuf_YZ, sendCount_YZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &sendbuf_YZ, 2*sendCount_YZ*sizeof(double)); // Allocate device memory
//...................................................................................... //......................................................................................
ScaLBL_AllocateZeroCopy((void **) &recvbuf_x, 5*recvCount_x*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_x, 2*5*recvCount_x*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_X, 5*recvCount_X*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_X, 2*5*recvCount_X*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_y, 5*recvCount_y*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_y, 2*5*recvCount_y*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Y, 5*recvCount_Y*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_Y, 2*5*recvCount_Y*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_z, 5*recvCount_z*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_z, 2*5*recvCount_z*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Z, 5*recvCount_Z*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_Z, 2*5*recvCount_Z*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xy, recvCount_xy*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_xy, 2*recvCount_xy*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xY, recvCount_xY*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_xY, 2*recvCount_xY*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xy, recvCount_Xy*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xy, 2*recvCount_Xy*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XY, recvCount_XY*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_XY, 2*recvCount_XY*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xz, recvCount_xz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_xz, 2*recvCount_xz*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_xZ, recvCount_xZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_xZ, 2*recvCount_xZ*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xz, recvCount_Xz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_Xz, 2*recvCount_Xz*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_XZ, recvCount_XZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_XZ, 2*recvCount_XZ*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_yz, recvCount_yz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_yz, 2*recvCount_yz*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_yZ, recvCount_yZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_yZ, 2*recvCount_yZ*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_Yz, recvCount_Yz*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_Yz, 2*recvCount_Yz*sizeof(double)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &recvbuf_YZ, recvCount_YZ*sizeof(double)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &recvbuf_YZ, 2*recvCount_YZ*sizeof(double)); // Allocate device memory
//...................................................................................... //......................................................................................
ScaLBL_AllocateZeroCopy((void **) &dvcSendList_x, sendCount_x*sizeof(int)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &dvcSendList_x, sendCount_x*sizeof(int)); // Allocate device memory
ScaLBL_AllocateZeroCopy((void **) &dvcSendList_X, sendCount_X*sizeof(int)); // Allocate device memory ScaLBL_AllocateZeroCopy((void **) &dvcSendList_X, sendCount_X*sizeof(int)); // Allocate device memory
@ -1125,6 +1125,7 @@ void ScaLBL_Communicator::RecvGrad(double *phi, double *grad){
ScaLBL_Gradient_Unpack(1.0,-1,0,0,dvcRecvDist_x,0,recvCount_x,recvbuf_x,phi,grad,N); ScaLBL_Gradient_Unpack(1.0,-1,0,0,dvcRecvDist_x,0,recvCount_x,recvbuf_x,phi,grad,N);
ScaLBL_Gradient_Unpack(0.5,-1,-1,0,dvcRecvDist_x,recvCount_x,recvCount_x,recvbuf_x,phi,grad,N); ScaLBL_Gradient_Unpack(0.5,-1,-1,0,dvcRecvDist_x,recvCount_x,recvCount_x,recvbuf_x,phi,grad,N);
ScaLBL_Gradient_Unpack(0.5,-1,1,0,dvcRecvDist_x,2*recvCount_x,recvCount_x,recvbuf_x,phi,grad,N); ScaLBL_Gradient_Unpack(0.5,-1,1,0,dvcRecvDist_x,2*recvCount_x,recvCount_x,recvbuf_x,phi,grad,N);
ScaLBL_Gradient_Unpack(0.5,-1,0,-1,dvcRecvDist_x,3*recvCount_x,recvCount_x,recvbuf_x,phi,grad,N);
ScaLBL_Gradient_Unpack(0.5,-1,0,1,dvcRecvDist_x,4*recvCount_x,recvCount_x,recvbuf_x,phi,grad,N); ScaLBL_Gradient_Unpack(0.5,-1,0,1,dvcRecvDist_x,4*recvCount_x,recvCount_x,recvbuf_x,phi,grad,N);
//................................................................................... //...................................................................................
//...Packing for X face(1,7,9,11,13)................................ //...Packing for X face(1,7,9,11,13)................................

View File

@ -71,7 +71,7 @@ extern "C" void ScaLBL_D3Q19_AAeven_BGK(double *dist, int start, int finish, int
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);
// GREYSCALE MODEL // GREYSCALE MODEL (Single-component)
extern "C" void ScaLBL_D3Q19_GreyIMRT_Init(double *Dist, int Np, double Den); extern "C" void ScaLBL_D3Q19_GreyIMRT_Init(double *Dist, int Np, double Den);
@ -87,6 +87,119 @@ extern "C" void ScaLBL_D3Q19_AAeven_Greyscale_IMRT(double *dist, int start, int
extern "C" void ScaLBL_D3Q19_AAodd_Greyscale_IMRT(int *neighborList, double *dist, int start, int finish, int Np, double rlx, double rlx_eff, double Fx, double Fy, double Fz, extern "C" void ScaLBL_D3Q19_AAodd_Greyscale_IMRT(int *neighborList, double *dist, int start, int finish, int Np, double rlx, double rlx_eff, double Fx, double Fy, double Fz,
double *Poros,double *Perm, double *Velocity,double Den,double *Pressure); double *Poros,double *Perm, double *Velocity,double Den,double *Pressure);
extern "C" void ScaLBL_D3Q19_AAeven_Greyscale_MRT(double *dist, int start, int finish, int Np, double rlx, double rlx_eff, double Fx, double Fy, double Fz,
double *Poros,double *Perm, double *Velocity,double Den,double *Pressure);
extern "C" void ScaLBL_D3Q19_AAodd_Greyscale_MRT(int *neighborList, double *dist, int start, int finish, int Np, double rlx, double rlx_eff, double Fx, double Fy, double Fz,
double *Poros,double *Perm, double *Velocity,double Den,double *Pressure);
// GREYSCALE FREE-ENERGY MODEL (Two-component)
//extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleFE(double *dist, double *Aq, double *Bq, double *Den,
// double *DenGradA, double *DenGradB, double *SolidForce, int start, int finish, int Np,
// double tauA,double tauB,double tauA_eff,double tauB_eff,double rhoA,double rhoB,double Gsc, double Gx, double Gy, double Gz,
// double *Poros,double *Perm, double *Velocity,double *Pressure);
//
//extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleFE(int *neighborList, double *dist, double *Aq, double *Bq, double *Den,
// double *DenGradA, double *DenGradB, double *SolidForce, int start, int finish, int Np,
// double tauA,double tauB,double tauA_eff,double tauB_eff,double rhoA,double rhoB,double Gsc, double Gx, double Gy, double Gz,
// double *Poros,double *Perm, double *Velocity,double *Pressure);
//
//extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleFEChem(double *dist, double *Cq, double *Phi, double *SolidForce, int start, int finish, int Np,
// double tauA,double tauB,double tauA_eff,double tauB_eff,double rhoA,double rhoB,double gamma,double kappaA,double kappaB,double lambdaA,double lambdaB,
// double Gx, double Gy, double Gz,
// double *Poros,double *Perm, double *Velocity,double *Pressure,double *PressureGrad,double *PressTensorGrad,double *PhiLap);
//
//extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleFEChem(int *neighborList, double *dist, double *Cq, double *Phi, double *SolidForce, int start, int finish, int Np,
// double tauA,double tauB,double tauA_eff,double tauB_eff,double rhoA,double rhoB,double gamma,double kappaA,double kappaB,double lambdaA,double lambdaB,
// double Gx, double Gy, double Gz,
// double *Poros,double *Perm, double *Velocity,double *Pressure,double *PressureGrad,double *PressTensorGrad,double *PhiLap);
//
//extern "C" void ScaLBL_D3Q7_GreyscaleFE_Init(double *Den, double *Cq, double *PhiLap, double gamma, double kappaA, double kappaB, double lambdaA, double lambdaB, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_GreyscaleFE_IMRT_Init(double *dist, double *Den, double rhoA, double rhoB, int Np);
//
//extern "C" void ScaLBL_D3Q7_AAodd_GreyscaleFEDensity(int *NeighborList, double *Aq, double *Bq, double *Den, double *Phi, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q7_AAeven_GreyscaleFEDensity(double *Aq, double *Bq, double *Den, double *Phi, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q7_AAodd_GreyscaleFEPhi(int *NeighborList, double *Cq, double *Phi, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q7_AAeven_GreyscaleFEPhi(double *Cq, double *Phi, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_GreyscaleFE_Gradient(int *neighborList, double *Den, double *DenGrad, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_GreyscaleFE_Laplacian(int *neighborList, double *Den, double *DenLap, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_GreyscaleFE_Pressure(double *dist, double *Den, double *Porosity,double *Velocity,
// double *Pressure, double rhoA,double rhoB, int Np);
//
//extern "C" void ScaLBL_D3Q19_GreyscaleFE_PressureTensor(int *neighborList, double *Phi,double *Pressure, double *PressTensor, double *PhiLap,
// double kappaA,double kappaB,double lambdaA,double lambdaB, int start, int finish, int Np);
// GREYSCALE SHAN-CHEN MODEL (Two-component)
//extern "C" void ScaLBL_D3Q19_GreyscaleSC_Init(int *Map, double *distA, double *distB, double *DenA, double *DenB, int Np);
//
//extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleSC_Density(int *NeighborList, int *Map, double *distA, double *distB, double *DenA, double *DenB, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleSC_Density(int *Map, double *distA, double *distB, double *DenA, double *DenB, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleSC_MRT(int *neighborList, int *Mpa, double *distA, double *distB, double *DenA,double *DenB, double *DenGradA, double *DenGradB,
// double *SolidForceA, double *SolidForceB, double *Poros,double *Perm, double *Velocity,double *Pressure,
// double tauA,double tauB,double tauA_eff,double tauB_eff, double Gsc, double Gx, double Gy, double Gz,
// int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleSC_MRT(int *Map,double *distA, double *distB, double *DenA,double *DenB, double *DenGradA, double *DenGradB,
// double *SolidForceA, double *SolidForceB, double *Poros,double *Perm, double *Velocity,double *Pressure,
// double tauA,double tauB,double tauA_eff,double tauB_eff, double Gsc, double Gx, double Gy, double Gz,
// int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleSC_BGK(int *neighborList, int *Map, double *distA, double *distB, double *DenA, double *DenB, double *DenGradA, double *DenGradB,
// double *SolidForceA, double *SolidForceB, double *Poros,double *Perm, double *Velocity,double *Pressure,
// double tauA,double tauB,double tauA_eff,double tauB_eff, double Gsc, double Gx, double Gy, double Gz,
// int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleSC_BGK(int *Map, double *distA, double *distB, double *DenA, double *DenB, double *DenGradA, double *DenGradB,
// double *SolidForceA, double *SolidForceB, double *Poros,double *Perm, double *Velocity,double *Pressure,
// double tauA,double tauB,double tauA_eff,double tauB_eff, double Gsc, double Gx, double Gy, double Gz,
// int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_GreyscaleSC_Gradient(int *neighborList, int *Map, double *Den, double *DenGrad, int strideY, int strideZ,int start, int finish, int Np);
//
//extern "C" void ScaLBL_GreyscaleSC_BC_z(int *list, int *Map, double *DenA, double *DenB, double vA, double vB, int count);
//
//extern "C" void ScaLBL_GreyscaleSC_BC_Z(int *list, int *Map, double *DenA, double *DenB, double vA, double vB, int count);
//
//extern "C" void ScaLBL_GreyscaleSC_AAeven_Pressure_BC_z(int *list, double *distA, double *distB, double dinA, double dinB, int count, int N);
//
//extern "C" void ScaLBL_GreyscaleSC_AAeven_Pressure_BC_Z(int *list, double *distA, double *distB, double doutA, double doutB, int count, int N);
//
//extern "C" void ScaLBL_GreyscaleSC_AAodd_Pressure_BC_z(int *neighborList, int *list, double *distA, double *distB, double dinA, double dinB, int count, int N);
//
//extern "C" void ScaLBL_GreyscaleSC_AAodd_Pressure_BC_Z(int *neighborList, int *list, double *distA, double *distB, double doutA, double doutB, int count, int N);
// GREYSCALE COLOR MODEL (Two-component)
//extern "C" void ScaLBL_D3Q19_GreyscaleColor_Init(double *dist, double *Porosity, int Np);
//extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor(int *Map, double *dist, double *Aq, double *Bq, double *Den,
// double *ColorGrad,double *Phi,double *GreySolidGrad, double *Poros,double *Perm,double *Vel,
// double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff, double alpha, double beta,
// double Fx, double Fy, double Fz, int strideY, int strideZ, int start, int finish, int Np);
//
//extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor(int *d_neighborList, int *Map, double *dist, double *Aq, double *Bq, double *Den,
// double *ColorGrad,double *Phi, double *GreySolidGrad, double *Poros,double *Perm,double *Vel,
// double rhoA, double rhoB, double tauA, double tauB, double tauA_eff,double tauB_eff, double alpha, double beta,
// double Fx, double Fy, double Fz, int strideY, int strideZ, int start, int finish, int Np);
extern "C" void ScaLBL_D3Q19_AAeven_GreyscaleColor(int *Map, double *dist, double *Aq, double *Bq, double *Den,
double *Phi,double *GreySolidGrad, double *Poros,double *Perm,double *Vel,
double rhoA, double rhoB, double tauA, double tauB,double tauA_eff,double tauB_eff, double alpha, double beta,
double Fx, double Fy, double Fz, int strideY, int strideZ, int start, int finish, int Np);
extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor(int *d_neighborList, int *Map, double *dist, double *Aq, double *Bq, double *Den,
double *Phi, double *GreySolidGrad, double *Poros,double *Perm,double *Vel,
double rhoA, double rhoB, double tauA, double tauB, double tauA_eff,double tauB_eff, double alpha, double beta,
double Fx, double Fy, double Fz, int strideY, int strideZ, int start, int finish, int Np);
// MRT MODEL // MRT MODEL
extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int Np, double rlx_setA, double rlx_setB, double Fx, extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int Np, double rlx_setA, double rlx_setB, double Fx,
@ -200,6 +313,8 @@ public:
int MemoryOptimizedLayoutAA(IntArray &Map, int *neighborList, signed char *id, int Np); int MemoryOptimizedLayoutAA(IntArray &Map, int *neighborList, signed char *id, int Np);
void SendD3Q19AA(double *dist); void SendD3Q19AA(double *dist);
void RecvD3Q19AA(double *dist); void RecvD3Q19AA(double *dist);
// void BiSendD3Q7(double *A_even, double *A_odd, double *B_even, double *B_odd);
// void BiRecvD3Q7(double *A_even, double *A_odd, double *B_even, double *B_odd);
void BiSendD3Q7AA(double *Aq, double *Bq); void BiSendD3Q7AA(double *Aq, double *Bq);
void BiRecvD3Q7AA(double *Aq, double *Bq); void BiRecvD3Q7AA(double *Aq, double *Bq);
void TriSendD3Q7AA(double *Aq, double *Bq, double *Cq); void TriSendD3Q7AA(double *Aq, double *Bq, double *Cq);
@ -217,6 +332,12 @@ public:
void D3Q19_Reflection_BC_z(double *fq); void D3Q19_Reflection_BC_z(double *fq);
void D3Q19_Reflection_BC_Z(double *fq); void D3Q19_Reflection_BC_Z(double *fq);
double D3Q19_Flux_BC_z(int *neighborList, double *fq, double flux, int time); double D3Q19_Flux_BC_z(int *neighborList, double *fq, double flux, int time);
void GreyscaleSC_BC_z(int *Map, double *DenA, double *DenB, double vA, double vB);
void GreyscaleSC_BC_Z(int *Map, double *DenA, double *DenB, double vA, double vB);
void GreyscaleSC_Pressure_BC_z(int *neighborList, double *fqA, double *fqB, double dinA, double dinB, int time);
void GreyscaleSC_Pressure_BC_Z(int *neighborList, double *fqA, double *fqB, double doutA, double doutB, int time);
// void TestSendD3Q19(double *f_even, double *f_odd);
// void TestRecvD3Q19(double *f_even, double *f_odd);
// Debugging and unit testing functions // Debugging and unit testing functions
void PrintD3Q19(); void PrintD3Q19();

View File

@ -99,33 +99,6 @@ extern "C" void ScaLBL_D3Q19_Init(double *dist, int Np)
} }
} }
extern "C" void ScaLBL_D3Q19_GreyIMRT_Init(double *dist, int Np, double Den)
{
int n;
for (n=0; n<Np; n++){
dist[n] = Den - 0.6666666666666667;
dist[Np+n] = 0.055555555555555555; //double(100*n)+1.f;
dist[2*Np+n] = 0.055555555555555555; //double(100*n)+2.f;
dist[3*Np+n] = 0.055555555555555555; //double(100*n)+3.f;
dist[4*Np+n] = 0.055555555555555555; //double(100*n)+4.f;
dist[5*Np+n] = 0.055555555555555555; //double(100*n)+5.f;
dist[6*Np+n] = 0.055555555555555555; //double(100*n)+6.f;
dist[7*Np+n] = 0.0277777777777778; //double(100*n)+7.f;
dist[8*Np+n] = 0.0277777777777778; //double(100*n)+8.f;
dist[9*Np+n] = 0.0277777777777778; //double(100*n)+9.f;
dist[10*Np+n] = 0.0277777777777778; //double(100*n)+10.f;
dist[11*Np+n] = 0.0277777777777778; //double(100*n)+11.f;
dist[12*Np+n] = 0.0277777777777778; //double(100*n)+12.f;
dist[13*Np+n] = 0.0277777777777778; //double(100*n)+13.f;
dist[14*Np+n] = 0.0277777777777778; //double(100*n)+14.f;
dist[15*Np+n] = 0.0277777777777778; //double(100*n)+15.f;
dist[16*Np+n] = 0.0277777777777778; //double(100*n)+16.f;
dist[17*Np+n] = 0.0277777777777778; //double(100*n)+17.f;
dist[18*Np+n] = 0.0277777777777778; //double(100*n)+18.f;
}
}
//************************************************************************* //*************************************************************************
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)
{ {

File diff suppressed because it is too large Load Diff

1366
cpu/GreyscaleColor.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -282,37 +282,6 @@ __global__ void dvc_ScaLBL_D3Q19_Init(double *dist, int Np)
} }
} }
__global__ void dvc_ScaLBL_D3Q19_GreyIMRT_Init(double *dist, int Np, double Den)
{
int n;
int S = Np/NBLOCKS/NTHREADS + 1;
for (int s=0; s<S; s++){
//........Get 1-D index for this thread....................
n = S*blockIdx.x*blockDim.x + s*blockDim.x + threadIdx.x;
if (n<Np ){
dist[n] = Den - 0.6666666666666667;
dist[Np+n] = 0.055555555555555555; //double(100*n)+1.f;
dist[2*Np+n] = 0.055555555555555555; //double(100*n)+2.f;
dist[3*Np+n] = 0.055555555555555555; //double(100*n)+3.f;
dist[4*Np+n] = 0.055555555555555555; //double(100*n)+4.f;
dist[5*Np+n] = 0.055555555555555555; //double(100*n)+5.f;
dist[6*Np+n] = 0.055555555555555555; //double(100*n)+6.f;
dist[7*Np+n] = 0.0277777777777778; //double(100*n)+7.f;
dist[8*Np+n] = 0.0277777777777778; //double(100*n)+8.f;
dist[9*Np+n] = 0.0277777777777778; //double(100*n)+9.f;
dist[10*Np+n] = 0.0277777777777778; //double(100*n)+10.f;
dist[11*Np+n] = 0.0277777777777778; //double(100*n)+11.f;
dist[12*Np+n] = 0.0277777777777778; //double(100*n)+12.f;
dist[13*Np+n] = 0.0277777777777778; //double(100*n)+13.f;
dist[14*Np+n] = 0.0277777777777778; //double(100*n)+14.f;
dist[15*Np+n] = 0.0277777777777778; //double(100*n)+15.f;
dist[16*Np+n] = 0.0277777777777778; //double(100*n)+16.f;
dist[17*Np+n] = 0.0277777777777778; //double(100*n)+17.f;
dist[18*Np+n] = 0.0277777777777778; //double(100*n)+18.f;
}
}
}
//************************************************************************* //*************************************************************************
__global__ void dvc_ScaLBL_D3Q19_Swap_Compact(int *neighborList, double *disteven, double *distodd, int Np, int q){ __global__ void dvc_ScaLBL_D3Q19_Swap_Compact(int *neighborList, double *disteven, double *distodd, int Np, int q){
int n,nn; int n,nn;
@ -2410,13 +2379,6 @@ extern "C" void ScaLBL_D3Q19_Init(double *dist, int Np){
} }
} }
extern "C" void ScaLBL_D3Q19_GreyIMRT_Init(double *dist, int Np, double Den){
dvc_ScaLBL_D3Q19_GreyIMRT_Init<<<NBLOCKS,NTHREADS >>>(dist, Np, Den);
cudaError_t err = cudaGetLastError();
if (cudaSuccess != err){
printf("CUDA error in ScaLBL_D3Q19_GreyIMRT_Init: %s \n",cudaGetErrorString(err));
}
}
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){
dvc_ScaLBL_D3Q19_Swap<<<NBLOCKS,NTHREADS >>>(ID, disteven, distodd, Nx, Ny, Nz); dvc_ScaLBL_D3Q19_Swap<<<NBLOCKS,NTHREADS >>>(ID, disteven, distodd, Nx, Ny, Nz);

File diff suppressed because it is too large Load Diff

2993
gpu/GreyscaleColor.cu Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
/*
Implementation of two-fluid greyscale color lattice boltzmann model
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <fstream>
#include "common/Communication.h"
#include "analysis/TwoPhase.h"
#include "analysis/runAnalysis.h"
#include "common/MPI_Helpers.h"
#include "ProfilerApp.h"
#include "threadpool/thread_pool.h"
class ScaLBL_GreyscaleColorModel{
public:
ScaLBL_GreyscaleColorModel(int RANK, int NP, MPI_Comm COMM);
~ScaLBL_GreyscaleColorModel();
// functions in they should be run
void ReadParams(string filename);
void ReadParams(std::shared_ptr<Database> db0);
void SetDomain();
void ReadInput();
void Create();
void Initialize();
void Run();
void WriteDebug();
bool Restart,pBC;
bool REVERSE_FLOW_DIRECTION;
int timestep,timestepMax;
int BoundaryCondition;
double tauA,tauB,rhoA,rhoB,alpha,beta;
double tauA_eff,tauB_eff;
double Fx,Fy,Fz,flux;
double din,dout,inletA,inletB,outletA,outletB;
double GreyPorosity;
bool greyMode;//run greyColor model if true
int Nx,Ny,Nz,N,Np;
int rank,nprocx,nprocy,nprocz,nprocs;
double Lx,Ly,Lz;
std::shared_ptr<Domain> Dm; // this domain is for analysis
std::shared_ptr<Domain> Mask; // this domain is for lbm
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm;
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm_Regular;
//std::shared_ptr<TwoPhase> Averages;
std::shared_ptr<SubPhase> Averages;
// input database
std::shared_ptr<Database> db;
std::shared_ptr<Database> domain_db;
std::shared_ptr<Database> greyscaleColor_db;
std::shared_ptr<Database> analysis_db;
std::shared_ptr<Database> vis_db;
IntArray Map;
signed char *id;
int *NeighborList;
int *dvcMap;
double *fq, *Aq, *Bq;
double *Den, *Phi;
//double *GreySolidPhi; //Model 2 & 3
double *GreySolidGrad;//Model 1 & 4
//double *ColorGrad;
double *Velocity;
double *Pressure;
double *Porosity_dvc;
double *Permeability_dvc;
private:
MPI_Comm comm;
int dist_mem_size;
int neighborSize;
// filenames
char LocalRankString[8];
char LocalRankFilename[40];
char LocalRestartFile[40];
//int rank,nprocs;
void LoadParams(std::shared_ptr<Database> db0);
void AssignComponentLabels();
void AssignGreySolidLabels();
void AssignGreyPoroPermLabels();
double ImageInit(std::string filename);
double MorphInit(const double beta, const double morph_delta);
double SeedPhaseField(const double seed_water_in_oil);
double MorphOpenConnected(double target_volume_change);
};

View File

@ -58,7 +58,7 @@ void ScaLBL_GreyscaleModel::ReadParams(string filename){
din=dout=1.0; din=dout=1.0;
flux=0.0; flux=0.0;
dp = 10.0; //unit of 'dp': voxel dp = 10.0; //unit of 'dp': voxel
CollisionType = 1; //1: IMRT; 2: BGK CollisionType = 1; //1: IMRT; 2: BGK; 3: MRT
// ---------------------- Greyscale Model parameters -----------------------// // ---------------------- Greyscale Model parameters -----------------------//
if (greyscale_db->keyExists( "timestepMax" )){ if (greyscale_db->keyExists( "timestepMax" )){
@ -98,6 +98,9 @@ void ScaLBL_GreyscaleModel::ReadParams(string filename){
if (collision == "BGK"){ if (collision == "BGK"){
CollisionType=2; CollisionType=2;
} }
else if (collision == "MRT"){
CollisionType=3;
}
// ------------------------------------------------------------------------// // ------------------------------------------------------------------------//
//------------------------ Other Domain parameters ------------------------// //------------------------ Other Domain parameters ------------------------//
@ -213,9 +216,9 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
for (int idx=0; idx<NLABELS; idx++) label_count[idx]=0; for (int idx=0; idx<NLABELS; idx++) label_count[idx]=0;
for (int k=1;k<Nz-1;k++){ for (int k=0;k<Nz;k++){
for (int j=1;j<Ny-1;j++){ for (int j=0;j<Ny;j++){
for (int i=1;i<Nx-1;i++){ for (int i=0;i<Nx;i++){
int n = k*Nx*Ny+j*Nx+i; int n = k*Nx*Ny+j*Nx+i;
VALUE=id[n]; VALUE=id[n];
// Assign the affinity from the paired list // Assign the affinity from the paired list
@ -244,9 +247,9 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
if (NLABELS != PermeabilityList.size()){ if (NLABELS != PermeabilityList.size()){
ERROR("Error: ComponentLabels and PermeabilityList must be the same length! \n"); ERROR("Error: ComponentLabels and PermeabilityList must be the same length! \n");
} }
for (int k=1;k<Nz-1;k++){ for (int k=0;k<Nz;k++){
for (int j=1;j<Ny-1;j++){ for (int j=0;j<Ny;j++){
for (int i=1;i<Nx-1;i++){ for (int i=0;i<Nx;i++){
int n = k*Nx*Ny+j*Nx+i; int n = k*Nx*Ny+j*Nx+i;
VALUE=id[n]; VALUE=id[n];
// Assign the affinity from the paired list // Assign the affinity from the paired list
@ -285,7 +288,7 @@ void ScaLBL_GreyscaleModel::AssignComponentLabels(double *Porosity, double *Perm
if (rank==0){ if (rank==0){
printf("Image resolution: %.5g [um/voxel]\n",Dm->voxel_length); printf("Image resolution: %.5g [um/voxel]\n",Dm->voxel_length);
printf("Component labels: %lu \n",NLABELS); printf("Number of component labels: %lu \n",NLABELS);
for (unsigned int idx=0; idx<NLABELS; idx++){ for (unsigned int idx=0; idx<NLABELS; idx++){
VALUE=LabelList[idx]; VALUE=LabelList[idx];
POROSITY=PorosityList[idx]; POROSITY=PorosityList[idx];
@ -337,7 +340,6 @@ void ScaLBL_GreyscaleModel::Create(){
neighborSize=18*(Np*sizeof(int)); neighborSize=18*(Np*sizeof(int));
//........................................................................... //...........................................................................
ScaLBL_AllocateDeviceMemory((void **) &NeighborList, neighborSize); ScaLBL_AllocateDeviceMemory((void **) &NeighborList, neighborSize);
ScaLBL_AllocateDeviceMemory((void **) &dvcMap, sizeof(int)*Np);
ScaLBL_AllocateDeviceMemory((void **) &fq, 19*dist_mem_size); ScaLBL_AllocateDeviceMemory((void **) &fq, 19*dist_mem_size);
ScaLBL_AllocateDeviceMemory((void **) &Permeability, sizeof(double)*Np); ScaLBL_AllocateDeviceMemory((void **) &Permeability, sizeof(double)*Np);
ScaLBL_AllocateDeviceMemory((void **) &Porosity, sizeof(double)*Np); ScaLBL_AllocateDeviceMemory((void **) &Porosity, sizeof(double)*Np);
@ -345,38 +347,8 @@ void ScaLBL_GreyscaleModel::Create(){
ScaLBL_AllocateDeviceMemory((void **) &Velocity, 3*sizeof(double)*Np); ScaLBL_AllocateDeviceMemory((void **) &Velocity, 3*sizeof(double)*Np);
//........................................................................... //...........................................................................
// Update GPU data structures // Update GPU data structures
if (rank==0) printf ("Setting up device map and neighbor list \n"); if (rank==0) printf ("Setting up device neighbor list \n");
fflush(stdout); fflush(stdout);
int *TmpMap;
TmpMap=new int[Np];
for (int k=1; k<Nz-1; k++){
for (int j=1; j<Ny-1; j++){
for (int i=1; i<Nx-1; i++){
int idx=Map(i,j,k);
if (!(idx < 0))
TmpMap[idx] = k*Nx*Ny+j*Nx+i;
}
}
}
// check that TmpMap is valid
for (int idx=0; idx<ScaLBL_Comm->LastExterior(); idx++){
int n = TmpMap[idx];
if (n > Nx*Ny*Nz){
printf("Bad value! idx=%i \n");
TmpMap[idx] = Nx*Ny*Nz-1;
}
}
for (int idx=ScaLBL_Comm->FirstInterior(); idx<ScaLBL_Comm->LastInterior(); idx++){
int n = TmpMap[idx];
if (n > Nx*Ny*Nz){
printf("Bad value! idx=%i \n");
TmpMap[idx] = Nx*Ny*Nz-1;
}
}
ScaLBL_CopyToDevice(dvcMap, TmpMap, sizeof(int)*Np);
ScaLBL_DeviceBarrier();
delete [] TmpMap;
// copy the neighbor list // copy the neighbor list
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize); ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
// initialize phi based on PhaseLabel (include solid component labels) // initialize phi based on PhaseLabel (include solid component labels)
@ -386,6 +358,8 @@ void ScaLBL_GreyscaleModel::Create(){
AssignComponentLabels(Poros,Perm); AssignComponentLabels(Poros,Perm);
ScaLBL_CopyToDevice(Porosity, Poros, Np*sizeof(double)); ScaLBL_CopyToDevice(Porosity, Poros, Np*sizeof(double));
ScaLBL_CopyToDevice(Permeability, Perm, Np*sizeof(double)); ScaLBL_CopyToDevice(Permeability, Perm, Np*sizeof(double));
delete [] Poros;
delete [] Perm;
} }
@ -402,6 +376,10 @@ void ScaLBL_GreyscaleModel::Initialize(){
ScaLBL_D3Q19_Init(fq, Np); ScaLBL_D3Q19_Init(fq, Np);
if (rank==0) printf("Collision model: BGK.\n"); if (rank==0) printf("Collision model: BGK.\n");
} }
else if (CollisionType==3){
ScaLBL_D3Q19_Init(fq, Np);
if (rank==0) printf("Collision model: MRT.\n");
}
else{ else{
if (rank==0) printf("Unknown collison type! IMRT collision is used.\n"); if (rank==0) printf("Unknown collison type! IMRT collision is used.\n");
ScaLBL_D3Q19_GreyIMRT_Init(fq, Np, Den); ScaLBL_D3Q19_GreyIMRT_Init(fq, Np, Den);
@ -483,6 +461,9 @@ void ScaLBL_GreyscaleModel::Run(){
case 2: case 2:
ScaLBL_D3Q19_AAodd_Greyscale(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc);
break; break;
case 3:
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: default:
ScaLBL_D3Q19_AAodd_Greyscale_IMRT(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale_IMRT(NeighborList, fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc);
break; break;
@ -501,6 +482,9 @@ void ScaLBL_GreyscaleModel::Run(){
case 2: case 2:
ScaLBL_D3Q19_AAodd_Greyscale(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc);
break; break;
case 3:
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: default:
ScaLBL_D3Q19_AAodd_Greyscale_IMRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAodd_Greyscale_IMRT(NeighborList, fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc);
break; break;
@ -517,6 +501,9 @@ void ScaLBL_GreyscaleModel::Run(){
case 2: case 2:
ScaLBL_D3Q19_AAeven_Greyscale(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc);
break; break;
case 3:
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: default:
ScaLBL_D3Q19_AAeven_Greyscale_IMRT(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale_IMRT(fq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc);
break; break;
@ -535,6 +522,9 @@ void ScaLBL_GreyscaleModel::Run(){
case 2: case 2:
ScaLBL_D3Q19_AAeven_Greyscale(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Pressure_dvc);
break; break;
case 3:
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: default:
ScaLBL_D3Q19_AAeven_Greyscale_IMRT(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc); ScaLBL_D3Q19_AAeven_Greyscale_IMRT(fq, 0, ScaLBL_Comm->LastExterior(), Np, rlx, rlx_eff, Fx, Fy, Fz,Porosity,Permeability,Velocity,Den,Pressure_dvc);
break; break;
@ -608,11 +598,6 @@ void ScaLBL_GreyscaleModel::Run(){
} }
} }
} }
//MPI_Allreduce(&vax_loc,&vax,1,MPI_DOUBLE,MPI_SUM,Mask->Comm);
//MPI_Allreduce(&vay_loc,&vay,1,MPI_DOUBLE,MPI_SUM,Mask->Comm);
//MPI_Allreduce(&vaz_loc,&vaz,1,MPI_DOUBLE,MPI_SUM,Mask->Comm);
//MPI_Allreduce(&count_loc,&count,1,MPI_DOUBLE,MPI_SUM,Mask->Comm);
vax = sumReduce( Mask->Comm, vax_loc); vax = sumReduce( Mask->Comm, vax_loc);
vay = sumReduce( Mask->Comm, vay_loc); vay = sumReduce( Mask->Comm, vay_loc);
vaz = sumReduce( Mask->Comm, vaz_loc); vaz = sumReduce( Mask->Comm, vaz_loc);

View File

@ -76,7 +76,6 @@ public:
signed char *id; signed char *id;
int *NeighborList; int *NeighborList;
int *dvcMap;
double *fq; double *fq;
double *Permeability;//grey voxel permeability double *Permeability;//grey voxel permeability
double *Porosity; double *Porosity;

View File

@ -4,6 +4,7 @@
ADD_LBPM_EXECUTABLE( lbpm_color_simulator ) ADD_LBPM_EXECUTABLE( lbpm_color_simulator )
ADD_LBPM_EXECUTABLE( lbpm_permeability_simulator ) ADD_LBPM_EXECUTABLE( lbpm_permeability_simulator )
ADD_LBPM_EXECUTABLE( lbpm_greyscale_simulator ) ADD_LBPM_EXECUTABLE( lbpm_greyscale_simulator )
ADD_LBPM_EXECUTABLE( lbpm_greyscaleColor_simulator )
#ADD_LBPM_EXECUTABLE( lbpm_BGK_simulator ) #ADD_LBPM_EXECUTABLE( lbpm_BGK_simulator )
#ADD_LBPM_EXECUTABLE( lbpm_color_macro_simulator ) #ADD_LBPM_EXECUTABLE( lbpm_color_macro_simulator )
ADD_LBPM_EXECUTABLE( lbpm_dfh_simulator ) ADD_LBPM_EXECUTABLE( lbpm_dfh_simulator )
@ -70,6 +71,7 @@ ADD_LBPM_TEST_PARALLEL( TestCommD3Q19 8 )
ADD_LBPM_TEST_1_2_4( testCommunication ) ADD_LBPM_TEST_1_2_4( testCommunication )
ADD_LBPM_TEST( TestWriter ) ADD_LBPM_TEST( TestWriter )
ADD_LBPM_TEST( TestDatabase ) ADD_LBPM_TEST( TestDatabase )
ADD_LBPM_TEST( TestSetDevice )
ADD_LBPM_PROVISIONAL_TEST( TestMicroCTReader ) ADD_LBPM_PROVISIONAL_TEST( TestMicroCTReader )
IF ( USE_NETCDF ) IF ( USE_NETCDF )
ADD_LBPM_TEST_PARALLEL( TestNetcdf 8 ) ADD_LBPM_TEST_PARALLEL( TestNetcdf 8 )

37
tests/TestSetDevice.cpp Normal file
View File

@ -0,0 +1,37 @@
#include <iostream>
#include "common/MPI_Helpers.h"
#include "common/Utilities.h"
#include "common/ScaLBL.h"
int main (int argc, char **argv)
{
MPI_Init(&argc,&argv);
int rank = MPI_WORLD_RANK();
int nprocs = MPI_WORLD_SIZE();
for (int i=0; i<nprocs; i++) {
if ( rank==i )
printf("%i of %i: Hello world\n",rank,nprocs);
MPI_Barrier(MPI_COMM_WORLD);
}
// Initialize compute device
ScaLBL_SetDevice(rank);
ScaLBL_DeviceBarrier();
MPI_Barrier(MPI_COMM_WORLD);
// Create a memory leak for valgrind to find
if ( nprocs==1 ) {
double *x = new double[1];
ASSERT(x!=NULL);
}
// set the error code
// Note: the error code should be consistent across all processors
int error = 0;
// Finished
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return error;
}

View File

@ -0,0 +1,71 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <fstream>
#include "models/GreyscaleColorModel.h"
#include "common/Utilities.h"
//#define WRITE_SURFACES
//*************************************************************************
// Implementation of Greyscale Two-Fluid Color LBM using CUDA
//*************************************************************************
using namespace std;
int main(int argc, char **argv)
{
// Initialize MPI and error handlers
Utilities::startup( argc, argv );
{ // Limit scope so variables that contain communicators will free before MPI_Finialize
MPI_Comm comm;
MPI_Comm_dup(MPI_COMM_WORLD,&comm);
int rank = comm_rank(comm);
int nprocs = comm_size(comm);
if (rank == 0){
printf("****************************************\n");
printf("Running Greyscale Two-Phase Calculation \n");
printf("****************************************\n");
}
// Initialize compute device
ScaLBL_SetDevice(rank);
ScaLBL_DeviceBarrier();
MPI_Barrier(comm);
PROFILE_ENABLE(1);
//PROFILE_ENABLE_TRACE();
//PROFILE_ENABLE_MEMORY();
PROFILE_SYNCHRONIZE();
PROFILE_START("Main");
Utilities::setErrorHandlers();
auto filename = argv[1];
ScaLBL_GreyscaleColorModel GreyscaleColor(rank,nprocs,comm);
GreyscaleColor.ReadParams(filename);
GreyscaleColor.SetDomain();
GreyscaleColor.ReadInput();
GreyscaleColor.Create(); // creating the model will create data structure to match the pore structure and allocate variables
GreyscaleColor.Initialize(); // initializing the model will set initial conditions for variables
GreyscaleColor.Run();
GreyscaleColor.WriteDebug();
PROFILE_STOP("Main");
PROFILE_SAVE("lbpm_greyscaleColor_simulator",1);
// ****************************************************
MPI_Barrier(comm);
MPI_Comm_free(&comm);
} // Limit scope so variables that contain communicators will free before MPI_Finialize
Utilities::shutdown();
}

View File

@ -6,33 +6,29 @@
#include <stdexcept> #include <stdexcept>
#include <fstream> #include <fstream>
#include "common/ScaLBL.h"
#include "common/Communication.h"
#include "common/MPI_Helpers.h"
#include "models/GreyscaleModel.h" #include "models/GreyscaleModel.h"
#include "common/Utilities.h"
//#define WRITE_SURFACES //#define WRITE_SURFACES
/* //****************************************************************
* Simulator for two-phase flow in porous media // Implementation of Greyscale Single-Fluid LBM using CUDA
* James E. McClure 2013-2014 //****************************************************************
*/
using namespace std; using namespace std;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
//*****************************************
// ***** MPI STUFF **************** // Initialize MPI and error handlers
//***************************************** Utilities::startup( argc, argv );
// Initialize MPI
int rank,nprocs; { // Limit scope so variables that contain communicators will free before MPI_Finialize
MPI_Init(&argc,&argv);
MPI_Comm comm = MPI_COMM_WORLD; MPI_Comm comm;
MPI_Comm_rank(comm,&rank); MPI_Comm_dup(MPI_COMM_WORLD,&comm);
MPI_Comm_size(comm,&nprocs); int rank = comm_rank(comm);
{ int nprocs = comm_size(comm);
// parallel domain size (# of sub-domains)
if (rank == 0){ if (rank == 0){
printf("********************************************************\n"); printf("********************************************************\n");
@ -40,24 +36,37 @@ int main(int argc, char **argv)
printf("********************************************************\n"); printf("********************************************************\n");
} }
// Initialize compute device // Initialize compute device
int device=ScaLBL_SetDevice(rank); ScaLBL_SetDevice(rank);
NULL_USE(device);
ScaLBL_DeviceBarrier(); ScaLBL_DeviceBarrier();
MPI_Barrier(comm); MPI_Barrier(comm);
ScaLBL_GreyscaleModel Greyscale(rank,nprocs,comm); PROFILE_ENABLE(1);
//PROFILE_ENABLE_TRACE();
//PROFILE_ENABLE_MEMORY();
PROFILE_SYNCHRONIZE();
PROFILE_START("Main");
Utilities::setErrorHandlers();
auto filename = argv[1]; auto filename = argv[1];
ScaLBL_GreyscaleModel Greyscale(rank,nprocs,comm);
Greyscale.ReadParams(filename); Greyscale.ReadParams(filename);
Greyscale.SetDomain(); // this reads in the domain Greyscale.SetDomain();
Greyscale.ReadInput(); Greyscale.ReadInput();
Greyscale.Create(); // creating the model will create data structure to match the pore structure and allocate variables Greyscale.Create(); // creating the model will create data structure to match the pore structure and allocate variables
Greyscale.Initialize(); // initializing the model will set initial conditions for variables Greyscale.Initialize(); // initializing the model will set initial conditions for variables
Greyscale.Run(); Greyscale.Run();
//Greyscale.VelocityField(); Greyscale.VelocityField();
//Greyscale.WriteDebug(); //Greyscale.WriteDebug();
}
PROFILE_STOP("Main");
PROFILE_SAVE("lbpm_greyscale_simulator",1);
// **************************************************** // ****************************************************
MPI_Barrier(comm); MPI_Barrier(comm);
MPI_Finalize(); MPI_Comm_free(&comm);
// ****************************************************
} // Limit scope so variables that contain communicators will free before MPI_Finialize
Utilities::shutdown();
} }