From bf98d9aa232d49e6d70e53a202a6c11cfce04cf8 Mon Sep 17 00:00:00 2001 From: James E McClure Date: Wed, 3 Jun 2015 15:37:39 -0400 Subject: [PATCH] Adding support for signed distance from segmented images in parallel --- common/Domain.h | 4 +- common/TwoPhase.h | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/common/Domain.h b/common/Domain.h index 6f9bd84f..738f99a2 100755 --- a/common/Domain.h +++ b/common/Domain.h @@ -34,6 +34,7 @@ struct Domain{ BlobLabel.resize(Nx,Ny,Nz); BlobGraph.resize(18,MAX_BLOB_COUNT,MAX_BLOB_COUNT); BoundaryCondition = BC; + rank_info = RankInfoStruct(rank,nprocx,nprocy,nprocz); } ~Domain(); @@ -41,9 +42,10 @@ struct Domain{ int Nx,Ny,Nz,N; int iproc,jproc,kproc; int nprocx,nprocy,nprocz; - double Lx,Ly,Lz,Volume; + double Lx,Ly,Lz,Volume; int rank; int BoundaryCondition; + const RankInfoStruct; MPI_Group Group; // Group of processors associated with this domain MPI_Comm Comm; // MPI Communicator for this domain diff --git a/common/TwoPhase.h b/common/TwoPhase.h index afb70172..1fffd915 100644 --- a/common/TwoPhase.h +++ b/common/TwoPhase.h @@ -289,6 +289,7 @@ public: void UpdateMeshValues(); void UpdateSolid(); void ComputeDelPhi(); + void SSO(DoubleArray &Distance, char *ID, int timesteps); void ColorToSignedDistance(double Beta, double *ColorData, double *DistData); void ComputeLocal(); void ComputeLocalBlob(); @@ -300,6 +301,123 @@ public: }; +inline void TwoPhase::SSO(DoubleArray &Distance, char *ID, int timesteps){ + + int Q=26; + int q,i,j,k,n; + const static int D3Q27[26][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}, + {1,1,0},{-1,-1,0},{1,-1,0},{-1,1,0},{1,0,1},{-1,0,-1},{1,0,-1},{-1,0,1}, + {0,1,1},{0,-1,-1},{0,1,-1},{0,-1,1},{1,1,1},{-1,-1,-1},{1,1,-1},{-1,-1,1}, + {-1,1,-1},{1,-1,1},{1,-1,-1},{-1,1,1}}; + + double weights[26]; + // Compute the weights from the finite differences + for (q=0; q 0.0){ + for (q=0; q<26; q++){ + Cqx = 1.0*D3Q27[q][0]; + Cqy = 1.0*D3Q27[q][1]; + Cqz = 1.0*D3Q27[q][2]; + // get the associated neighbor + in = i + D3Q27[q][0]; + jn = j + D3Q27[q][1]; + kn = k + D3Q27[q][2]; + // make sure the neighbor is in the domain (periodic BC) + /* if (in < 0 ) in +=Nx; + if (jn < 0 ) jn +=Ny; + if (kn < 0 ) kn +=Nz; + if (!(in < Nx) ) in -=Nx; + if (!(jn < Ny) ) jn -=Ny; + if (!(kn < Nz) ) kn -=Nz; + */ // symmetric boundary + if (in < 0 ) in = i; + if (jn < 0 ) jn = j; + if (kn < 0 ) kn = k; + if (!(in < Nx) ) in = i; + if (!(jn < Ny) ) jn = k; + if (!(kn < Nz) ) kn = k; + // 1-D index + nn = kn*Nx*Ny + jn*Nx + in; + + // Compute the gradient using upwind finite differences + Dqx = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqx; + Dqy = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqy; + Dqz = weights[q]*(Distance(i,j,k) - Distance(in,jn,kn))*Cqz; + + // Only include upwind derivatives + if (sign*(nx*Cqx + ny*Cqy + nz*Cqz) < 0.0 ){ + + Dx += Dqx; + Dy += Dqy; + Dz += Dqz; + W += weights[q]; + } + } + // Normalize by the weight to get the approximation to the gradient + Dx /= W; + Dy /= W; + Dz /= W; + + norm = sqrt(Dx*Dx+Dy*Dy+Dz*Dz); + } + else{ + norm = 0.0; + } + Distance(i,j,k) += dt*sign*(1.0 - norm); + + // Disallow any change in phase + if (Distance(i,j,k)*2.0*(ID[n]-1.0) < 0) Distance(i,j,k) = -Distance(i,j,k); + } + } + } + + count++; + } +} + + void TwoPhase::ColorToSignedDistance(double Beta, double *ColorData, double *DistData){ double factor,temp,value;