Adding Database
This commit is contained in:
@@ -15,92 +15,131 @@
|
||||
#include "common/MPI_Helpers.h"
|
||||
#include "common/Communication.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Reading the domain information file
|
||||
void read_domain( int rank, int nprocs, MPI_Comm comm,
|
||||
int& nprocx, int& nprocy, int& nprocz, int& nx, int& ny, int& nz,
|
||||
int& nspheres, double& Lx, double& Ly, double& Lz )
|
||||
|
||||
|
||||
// Inline function to read line without a return argument
|
||||
static inline void fgetl( char * str, int num, FILE * stream )
|
||||
{
|
||||
if (rank==0){
|
||||
ifstream domain("Domain.in");
|
||||
domain >> nprocx;
|
||||
domain >> nprocy;
|
||||
domain >> nprocz;
|
||||
domain >> nx;
|
||||
domain >> ny;
|
||||
domain >> nz;
|
||||
domain >> nspheres;
|
||||
domain >> Lx;
|
||||
domain >> Ly;
|
||||
domain >> Lz;
|
||||
|
||||
}
|
||||
MPI_Barrier(comm);
|
||||
// Computational domain
|
||||
//.................................................
|
||||
MPI_Bcast(&nx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&ny,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocx,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocy,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nprocz,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&nspheres,1,MPI_INT,0,comm);
|
||||
MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm);
|
||||
MPI_Barrier(comm);
|
||||
char* ptr = fgets( str, num, stream );
|
||||
if ( 0 ) {char *temp = (char *)&ptr; temp++;}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Constructor/Destructor *
|
||||
* Constructors/Destructor *
|
||||
********************************************************/
|
||||
Domain::Domain(int nx, int ny, int nz, int rnk, int npx, int npy, int npz,
|
||||
double lx, double ly, double lz, int BC):
|
||||
Nx(0), Ny(0), Nz(0), iproc(0), jproc(0), nprocx(0), nprocy(0), nprocz(0),
|
||||
Lx(0), Ly(0), Lz(0), Volume(0), rank(0), BoundaryCondition(0),
|
||||
Group(MPI_GROUP_NULL), Comm(MPI_COMM_NULL),
|
||||
rank_x(0), rank_y(0), rank_z(0), rank_X(0), rank_Y(0), rank_Z(0),
|
||||
rank_xy(0), rank_XY(0), rank_xY(0), rank_Xy(0),
|
||||
rank_xz(0), rank_XZ(0), rank_xZ(0), rank_Xz(0),
|
||||
rank_yz(0), rank_YZ(0), rank_yZ(0), rank_Yz(0),
|
||||
sendCount_x(0), sendCount_y(0), sendCount_z(0), sendCount_X(0), sendCount_Y(0), sendCount_Z(0),
|
||||
sendCount_xy(0), sendCount_yz(0), sendCount_xz(0), sendCount_Xy(0), sendCount_Yz(0), sendCount_xZ(0),
|
||||
sendCount_xY(0), sendCount_yZ(0), sendCount_Xz(0), sendCount_XY(0), sendCount_YZ(0), sendCount_XZ(0),
|
||||
sendList_x(NULL), sendList_y(NULL), sendList_z(NULL), sendList_X(NULL), sendList_Y(NULL), sendList_Z(NULL),
|
||||
sendList_xy(NULL), sendList_yz(NULL), sendList_xz(NULL), sendList_Xy(NULL), sendList_Yz(NULL), sendList_xZ(NULL),
|
||||
sendList_xY(NULL), sendList_yZ(NULL), sendList_Xz(NULL), sendList_XY(NULL), sendList_YZ(NULL), sendList_XZ(NULL),
|
||||
sendBuf_x(NULL), sendBuf_y(NULL), sendBuf_z(NULL), sendBuf_X(NULL), sendBuf_Y(NULL), sendBuf_Z(NULL),
|
||||
sendBuf_xy(NULL), sendBuf_yz(NULL), sendBuf_xz(NULL), sendBuf_Xy(NULL), sendBuf_Yz(NULL), sendBuf_xZ(NULL),
|
||||
sendBuf_xY(NULL), sendBuf_yZ(NULL), sendBuf_Xz(NULL), sendBuf_XY(NULL), sendBuf_YZ(NULL), sendBuf_XZ(NULL),
|
||||
recvCount_x(0), recvCount_y(0), recvCount_z(0), recvCount_X(0), recvCount_Y(0), recvCount_Z(0),
|
||||
recvCount_xy(0), recvCount_yz(0), recvCount_xz(0), recvCount_Xy(0), recvCount_Yz(0), recvCount_xZ(0),
|
||||
recvCount_xY(0), recvCount_yZ(0), recvCount_Xz(0), recvCount_XY(0), recvCount_YZ(0), recvCount_XZ(0),
|
||||
recvList_x(NULL), recvList_y(NULL), recvList_z(NULL), recvList_X(NULL), recvList_Y(NULL), recvList_Z(NULL),
|
||||
recvList_xy(NULL), recvList_yz(NULL), recvList_xz(NULL), recvList_Xy(NULL), recvList_Yz(NULL), recvList_xZ(NULL),
|
||||
recvList_xY(NULL), recvList_yZ(NULL), recvList_Xz(NULL), recvList_XY(NULL), recvList_YZ(NULL), recvList_XZ(NULL),
|
||||
recvBuf_x(NULL), recvBuf_y(NULL), recvBuf_z(NULL), recvBuf_X(NULL), recvBuf_Y(NULL), recvBuf_Z(NULL),
|
||||
recvBuf_xy(NULL), recvBuf_yz(NULL), recvBuf_xz(NULL), recvBuf_Xy(NULL), recvBuf_Yz(NULL), recvBuf_xZ(NULL),
|
||||
recvBuf_xY(NULL), recvBuf_yZ(NULL), recvBuf_Xz(NULL), recvBuf_XY(NULL), recvBuf_YZ(NULL), recvBuf_XZ(NULL),
|
||||
sendData_x(NULL), sendData_y(NULL), sendData_z(NULL), sendData_X(NULL), sendData_Y(NULL), sendData_Z(NULL),
|
||||
sendData_xy(NULL), sendData_yz(NULL), sendData_xz(NULL), sendData_Xy(NULL), sendData_Yz(NULL), sendData_xZ(NULL),
|
||||
sendData_xY(NULL), sendData_yZ(NULL), sendData_Xz(NULL), sendData_XY(NULL), sendData_YZ(NULL), sendData_XZ(NULL),
|
||||
recvData_x(NULL), recvData_y(NULL), recvData_z(NULL), recvData_X(NULL), recvData_Y(NULL), recvData_Z(NULL),
|
||||
recvData_xy(NULL), recvData_yz(NULL), recvData_xz(NULL), recvData_Xy(NULL), recvData_Yz(NULL), recvData_xZ(NULL),
|
||||
recvData_xY(NULL), recvData_yZ(NULL), recvData_Xz(NULL), recvData_XY(NULL), recvData_YZ(NULL), recvData_XZ(NULL),
|
||||
id(NULL)
|
||||
Domain::Domain( int nx, int ny, int nz, int rnk, int npx, int npy, int npz,
|
||||
double lx, double ly, double lz, int BC):
|
||||
Nx(0), Ny(0), Nz(0), iproc(0), jproc(0), nprocx(0), nprocy(0), nprocz(0),
|
||||
Lx(0), Ly(0), Lz(0), Volume(0), rank(0), BoundaryCondition(0),
|
||||
Group(MPI_GROUP_NULL), Comm(MPI_COMM_NULL),
|
||||
rank_x(0), rank_y(0), rank_z(0), rank_X(0), rank_Y(0), rank_Z(0),
|
||||
rank_xy(0), rank_XY(0), rank_xY(0), rank_Xy(0),
|
||||
rank_xz(0), rank_XZ(0), rank_xZ(0), rank_Xz(0),
|
||||
rank_yz(0), rank_YZ(0), rank_yZ(0), rank_Yz(0),
|
||||
sendCount_x(0), sendCount_y(0), sendCount_z(0), sendCount_X(0), sendCount_Y(0), sendCount_Z(0),
|
||||
sendCount_xy(0), sendCount_yz(0), sendCount_xz(0), sendCount_Xy(0), sendCount_Yz(0), sendCount_xZ(0),
|
||||
sendCount_xY(0), sendCount_yZ(0), sendCount_Xz(0), sendCount_XY(0), sendCount_YZ(0), sendCount_XZ(0),
|
||||
sendList_x(NULL), sendList_y(NULL), sendList_z(NULL), sendList_X(NULL), sendList_Y(NULL), sendList_Z(NULL),
|
||||
sendList_xy(NULL), sendList_yz(NULL), sendList_xz(NULL), sendList_Xy(NULL), sendList_Yz(NULL), sendList_xZ(NULL),
|
||||
sendList_xY(NULL), sendList_yZ(NULL), sendList_Xz(NULL), sendList_XY(NULL), sendList_YZ(NULL), sendList_XZ(NULL),
|
||||
sendBuf_x(NULL), sendBuf_y(NULL), sendBuf_z(NULL), sendBuf_X(NULL), sendBuf_Y(NULL), sendBuf_Z(NULL),
|
||||
sendBuf_xy(NULL), sendBuf_yz(NULL), sendBuf_xz(NULL), sendBuf_Xy(NULL), sendBuf_Yz(NULL), sendBuf_xZ(NULL),
|
||||
sendBuf_xY(NULL), sendBuf_yZ(NULL), sendBuf_Xz(NULL), sendBuf_XY(NULL), sendBuf_YZ(NULL), sendBuf_XZ(NULL),
|
||||
recvCount_x(0), recvCount_y(0), recvCount_z(0), recvCount_X(0), recvCount_Y(0), recvCount_Z(0),
|
||||
recvCount_xy(0), recvCount_yz(0), recvCount_xz(0), recvCount_Xy(0), recvCount_Yz(0), recvCount_xZ(0),
|
||||
recvCount_xY(0), recvCount_yZ(0), recvCount_Xz(0), recvCount_XY(0), recvCount_YZ(0), recvCount_XZ(0),
|
||||
recvList_x(NULL), recvList_y(NULL), recvList_z(NULL), recvList_X(NULL), recvList_Y(NULL), recvList_Z(NULL),
|
||||
recvList_xy(NULL), recvList_yz(NULL), recvList_xz(NULL), recvList_Xy(NULL), recvList_Yz(NULL), recvList_xZ(NULL),
|
||||
recvList_xY(NULL), recvList_yZ(NULL), recvList_Xz(NULL), recvList_XY(NULL), recvList_YZ(NULL), recvList_XZ(NULL),
|
||||
recvBuf_x(NULL), recvBuf_y(NULL), recvBuf_z(NULL), recvBuf_X(NULL), recvBuf_Y(NULL), recvBuf_Z(NULL),
|
||||
recvBuf_xy(NULL), recvBuf_yz(NULL), recvBuf_xz(NULL), recvBuf_Xy(NULL), recvBuf_Yz(NULL), recvBuf_xZ(NULL),
|
||||
recvBuf_xY(NULL), recvBuf_yZ(NULL), recvBuf_Xz(NULL), recvBuf_XY(NULL), recvBuf_YZ(NULL), recvBuf_XZ(NULL),
|
||||
sendData_x(NULL), sendData_y(NULL), sendData_z(NULL), sendData_X(NULL), sendData_Y(NULL), sendData_Z(NULL),
|
||||
sendData_xy(NULL), sendData_yz(NULL), sendData_xz(NULL), sendData_Xy(NULL), sendData_Yz(NULL), sendData_xZ(NULL),
|
||||
sendData_xY(NULL), sendData_yZ(NULL), sendData_Xz(NULL), sendData_XY(NULL), sendData_YZ(NULL), sendData_XZ(NULL),
|
||||
recvData_x(NULL), recvData_y(NULL), recvData_z(NULL), recvData_X(NULL), recvData_Y(NULL), recvData_Z(NULL),
|
||||
recvData_xy(NULL), recvData_yz(NULL), recvData_xz(NULL), recvData_Xy(NULL), recvData_Yz(NULL), recvData_xZ(NULL),
|
||||
recvData_xY(NULL), recvData_yZ(NULL), recvData_Xz(NULL), recvData_XY(NULL), recvData_YZ(NULL), recvData_XZ(NULL),
|
||||
id(NULL)
|
||||
{
|
||||
Volume = nx*ny*nx*npx*npy*npz*1.0;
|
||||
Nx = nx+2; Ny = ny+2; Nz = nz+2;
|
||||
Lx = lx, Ly = ly, Lz = lz;
|
||||
rank = rnk;
|
||||
nprocx=npx; nprocy=npy; nprocz=npz;
|
||||
auto db = std::make_shared<Database>( );
|
||||
db->putScalar<int>( "BC", BC );
|
||||
db->putVector<int>( "nproc", { npx, npx, npx } );
|
||||
db->putVector<int>( "n", { nx, ny, nz } );
|
||||
db->putScalar<int>( "nspheres", 0 );
|
||||
db->putVector<double>( "L", { lx, ly, lz } );
|
||||
initialize( db );
|
||||
}
|
||||
Domain::Domain( std::shared_ptr<Database> db ):
|
||||
Nx(0), Ny(0), Nz(0), iproc(0), jproc(0), nprocx(0), nprocy(0), nprocz(0),
|
||||
Lx(0), Ly(0), Lz(0), Volume(0), rank(0), BoundaryCondition(0),
|
||||
Group(MPI_GROUP_NULL), Comm(MPI_COMM_NULL),
|
||||
rank_x(0), rank_y(0), rank_z(0), rank_X(0), rank_Y(0), rank_Z(0),
|
||||
rank_xy(0), rank_XY(0), rank_xY(0), rank_Xy(0),
|
||||
rank_xz(0), rank_XZ(0), rank_xZ(0), rank_Xz(0),
|
||||
rank_yz(0), rank_YZ(0), rank_yZ(0), rank_Yz(0),
|
||||
sendCount_x(0), sendCount_y(0), sendCount_z(0), sendCount_X(0), sendCount_Y(0), sendCount_Z(0),
|
||||
sendCount_xy(0), sendCount_yz(0), sendCount_xz(0), sendCount_Xy(0), sendCount_Yz(0), sendCount_xZ(0),
|
||||
sendCount_xY(0), sendCount_yZ(0), sendCount_Xz(0), sendCount_XY(0), sendCount_YZ(0), sendCount_XZ(0),
|
||||
sendList_x(NULL), sendList_y(NULL), sendList_z(NULL), sendList_X(NULL), sendList_Y(NULL), sendList_Z(NULL),
|
||||
sendList_xy(NULL), sendList_yz(NULL), sendList_xz(NULL), sendList_Xy(NULL), sendList_Yz(NULL), sendList_xZ(NULL),
|
||||
sendList_xY(NULL), sendList_yZ(NULL), sendList_Xz(NULL), sendList_XY(NULL), sendList_YZ(NULL), sendList_XZ(NULL),
|
||||
sendBuf_x(NULL), sendBuf_y(NULL), sendBuf_z(NULL), sendBuf_X(NULL), sendBuf_Y(NULL), sendBuf_Z(NULL),
|
||||
sendBuf_xy(NULL), sendBuf_yz(NULL), sendBuf_xz(NULL), sendBuf_Xy(NULL), sendBuf_Yz(NULL), sendBuf_xZ(NULL),
|
||||
sendBuf_xY(NULL), sendBuf_yZ(NULL), sendBuf_Xz(NULL), sendBuf_XY(NULL), sendBuf_YZ(NULL), sendBuf_XZ(NULL),
|
||||
recvCount_x(0), recvCount_y(0), recvCount_z(0), recvCount_X(0), recvCount_Y(0), recvCount_Z(0),
|
||||
recvCount_xy(0), recvCount_yz(0), recvCount_xz(0), recvCount_Xy(0), recvCount_Yz(0), recvCount_xZ(0),
|
||||
recvCount_xY(0), recvCount_yZ(0), recvCount_Xz(0), recvCount_XY(0), recvCount_YZ(0), recvCount_XZ(0),
|
||||
recvList_x(NULL), recvList_y(NULL), recvList_z(NULL), recvList_X(NULL), recvList_Y(NULL), recvList_Z(NULL),
|
||||
recvList_xy(NULL), recvList_yz(NULL), recvList_xz(NULL), recvList_Xy(NULL), recvList_Yz(NULL), recvList_xZ(NULL),
|
||||
recvList_xY(NULL), recvList_yZ(NULL), recvList_Xz(NULL), recvList_XY(NULL), recvList_YZ(NULL), recvList_XZ(NULL),
|
||||
recvBuf_x(NULL), recvBuf_y(NULL), recvBuf_z(NULL), recvBuf_X(NULL), recvBuf_Y(NULL), recvBuf_Z(NULL),
|
||||
recvBuf_xy(NULL), recvBuf_yz(NULL), recvBuf_xz(NULL), recvBuf_Xy(NULL), recvBuf_Yz(NULL), recvBuf_xZ(NULL),
|
||||
recvBuf_xY(NULL), recvBuf_yZ(NULL), recvBuf_Xz(NULL), recvBuf_XY(NULL), recvBuf_YZ(NULL), recvBuf_XZ(NULL),
|
||||
sendData_x(NULL), sendData_y(NULL), sendData_z(NULL), sendData_X(NULL), sendData_Y(NULL), sendData_Z(NULL),
|
||||
sendData_xy(NULL), sendData_yz(NULL), sendData_xz(NULL), sendData_Xy(NULL), sendData_Yz(NULL), sendData_xZ(NULL),
|
||||
sendData_xY(NULL), sendData_yZ(NULL), sendData_Xz(NULL), sendData_XY(NULL), sendData_YZ(NULL), sendData_XZ(NULL),
|
||||
recvData_x(NULL), recvData_y(NULL), recvData_z(NULL), recvData_X(NULL), recvData_Y(NULL), recvData_Z(NULL),
|
||||
recvData_xy(NULL), recvData_yz(NULL), recvData_xz(NULL), recvData_Xy(NULL), recvData_Yz(NULL), recvData_xZ(NULL),
|
||||
recvData_xY(NULL), recvData_yZ(NULL), recvData_Xz(NULL), recvData_XY(NULL), recvData_YZ(NULL), recvData_XZ(NULL),
|
||||
id(NULL)
|
||||
{
|
||||
initialize( db );
|
||||
}
|
||||
void Domain::initialize( std::shared_ptr<Database> db )
|
||||
{
|
||||
d_db = db;
|
||||
auto nproc = d_db->getVector<int>("nproc");
|
||||
auto n = d_db->getVector<int>("n");
|
||||
auto L = d_db->getVector<double>("L");
|
||||
ASSERT( n.size() == 3u );
|
||||
ASSERT( L.size() == 3u );
|
||||
ASSERT( nproc.size() == 3u );
|
||||
int nx = n[0];
|
||||
int ny = n[1];
|
||||
int nz = n[2];
|
||||
Lx = L[0];
|
||||
Ly = L[1];
|
||||
Lz = L[2];
|
||||
Nx = nx+2;
|
||||
Ny = ny+2;
|
||||
Nz = nz+2;
|
||||
nprocx = nproc[0];
|
||||
nprocy = nproc[1];
|
||||
nprocz = nproc[2];
|
||||
N = Nx*Ny*Nz;
|
||||
Volume = nx*ny*nx*nprocx*nprocy*nprocz*1.0;
|
||||
id = new char[N];
|
||||
memset(id,0,N);
|
||||
BoundaryCondition = BC;
|
||||
BoundaryCondition = d_db->getScalar<int>("BC");
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
rank_info=RankInfoStruct(rank,nprocx,nprocy,nprocz);
|
||||
int nprocs;
|
||||
MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
|
||||
INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!");
|
||||
}
|
||||
Domain::~Domain()
|
||||
{
|
||||
@@ -1240,3 +1279,447 @@ void Domain::CommunicateMeshHalo(DoubleArray &Mesh)
|
||||
UnpackMeshData(recvList_YZ, recvCount_YZ ,recvData_YZ, MeshData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
double SSO(DoubleArray &Distance, char *ID, Domain &Dm, int timesteps){
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
int Q=26;
|
||||
int q,i,j,k;
|
||||
double dt=0.1;
|
||||
int in,jn,kn;
|
||||
double Dqx,Dqy,Dqz,Dx,Dy,Dz,W;
|
||||
double nx,ny,nz,Cqx,Cqy,Cqz,sign,norm;
|
||||
double TotalVariation=0.0;
|
||||
|
||||
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<Q; q++){
|
||||
weights[q] = sqrt(1.0*(D3Q27[q][0]*D3Q27[q][0]) + 1.0*(D3Q27[q][1]*D3Q27[q][1]) + 1.0*(D3Q27[q][2]*D3Q27[q][2]));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
int count = 0;
|
||||
while (count < timesteps){
|
||||
|
||||
// Communicate the halo of values
|
||||
fillData.fill(Distance);
|
||||
|
||||
TotalVariation=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 = Distance(i,j,k) / fabs(Distance(i,j,k));
|
||||
sign = -1;
|
||||
if (ID[n] == 1) sign = 1;
|
||||
/*
|
||||
if (!(i+1<Nx)) nx=0.5*Distance(i,j,k);
|
||||
else nx=0.5*Distance(i+1,j,k);;
|
||||
if (!(j+1<Ny)) ny=0.5*Distance(i,j,k);
|
||||
else ny=0.5*Distance(i,j+1,k);
|
||||
if (!(k+1<Nz)) nz=0.5*Distance(i,j,k);
|
||||
else nz=0.5*Distance(i,j,k+1);
|
||||
if (i<1) nx-=0.5*Distance(i,j,k);
|
||||
else nx-=0.5*Distance(i-1,j,k);
|
||||
if (j<1) ny-=0.5*Distance(i,j,k);
|
||||
else ny-=0.5*Distance(i,j-1,k);
|
||||
if (k<1) nz-=0.5*Distance(i,j,k);
|
||||
else nz-=0.5*Distance(i,j,k-1);
|
||||
*/
|
||||
|
||||
//............Compute the Gradient...................................
|
||||
nx = 0.5*(Distance(i+1,j,k) - Distance(i-1,j,k));
|
||||
ny = 0.5*(Distance(i,j+1,k) - Distance(i,j-1,k));
|
||||
nz = 0.5*(Distance(i,j,k+1) - Distance(i,j,k-1));
|
||||
|
||||
W = 0.0; Dx = Dy = Dz = 0.0;
|
||||
// also ignore places where the gradient is zero since this will not
|
||||
// result in any local change to Distance
|
||||
if (nx*nx+ny*ny+nz*nz > 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;
|
||||
* don't need this in parallel since MPI handles the halos
|
||||
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;
|
||||
*/
|
||||
|
||||
// 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
|
||||
if (fabs(W) > 0.0){
|
||||
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);
|
||||
TotalVariation += 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
TotalVariation /= (Dm.Nx-2)*(Dm.Ny-2)*(Dm.Nz-2);
|
||||
count++;
|
||||
}
|
||||
|
||||
return TotalVariation;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
FILE *fid = fopen("pack.out","rb");
|
||||
INSIST(fid!=NULL,"Error opening pack.out");
|
||||
//.........Trash the header lines..........
|
||||
char line[100];
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
fgetl(line, 100, fid);
|
||||
//........read the spheres..................
|
||||
// We will read until a blank like or end-of-file is reached
|
||||
int count = 0;
|
||||
while ( !feof(fid) && fgets(line,100,fid)!=NULL ) {
|
||||
char* line2 = line;
|
||||
List_cx[count] = strtod(line2,&line2);
|
||||
List_cy[count] = strtod(line2,&line2);
|
||||
List_cz[count] = strtod(line2,&line2);
|
||||
List_rad[count] = strtod(line2,&line2);
|
||||
count++;
|
||||
}
|
||||
cout << "Number of spheres extracted is: " << count << endl;
|
||||
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,
|
||||
double Lx, double Ly, double Lz, int Nx, int Ny, int Nz,
|
||||
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;
|
||||
int N = Nx*Ny*Nz; // Domain size, including the halo
|
||||
double hx,hy,hz;
|
||||
double x,y,z;
|
||||
double cx,cy,cz,r;
|
||||
int imin,imax,jmin,jmax,kmin,kmax;
|
||||
int p,i,j,k,n;
|
||||
//............................................
|
||||
double min_x,min_y,min_z;
|
||||
// double max_x,max_y,max_z;
|
||||
//............................................
|
||||
// Lattice spacing for the entire domain
|
||||
// It should generally be true that hx=hy=hz
|
||||
// Otherwise, you will end up with ellipsoids
|
||||
hx = Lx/(Nx*nprocx-1);
|
||||
hy = Ly/(Ny*nprocy-1);
|
||||
hz = Lz/(Nz*nprocz-1);
|
||||
//............................................
|
||||
// Get maximum and minimum for this domain
|
||||
// Halo is included !
|
||||
min_x = double(iproc*Nx-1)*hx;
|
||||
min_y = double(jproc*Ny-1)*hy;
|
||||
min_z = double(kproc*Nz-1)*hz;
|
||||
// max_x = ((iproc+1)*Nx+1)*hx;
|
||||
// max_y = ((jproc+1)*Ny+1)*hy;
|
||||
// max_z = ((kproc+1)*Nz+1)*hz;
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// Pre-initialize local ID
|
||||
for (n=0;n<N;n++){
|
||||
ID[n]=1;
|
||||
}
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// .........Loop over the spheres.............
|
||||
for (p=0;p<nspheres;p++){
|
||||
// Get the sphere from the list, map to local min
|
||||
cx = List_cx[p] - min_x;
|
||||
cy = List_cy[p] - min_y;
|
||||
cz = List_cz[p] - min_z;
|
||||
r = List_rad[p];
|
||||
// Check if
|
||||
// Range for this sphere in global indexing
|
||||
imin = int ((cx-r)/hx)-1;
|
||||
imax = int ((cx+r)/hx)+1;
|
||||
jmin = int ((cy-r)/hy)-1;
|
||||
jmax = int ((cy+r)/hy)+1;
|
||||
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;
|
||||
// Loop over the domain for this sphere (may be null)
|
||||
for (i=imin;i<imax;i++){
|
||||
for (j=jmin;j<jmax;j++){
|
||||
for (k=kmin;k<kmax;k++){
|
||||
// Initialize ID value to 'fluid (=1)'
|
||||
x = i*hx;
|
||||
y = j*hy;
|
||||
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){
|
||||
value=0;
|
||||
}
|
||||
// get the position in the list
|
||||
n = k*Nx*Ny+j*Nx+i;
|
||||
if ( ID[n] != 0 ){
|
||||
ID[n] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 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
|
||||
double hx,hy,hz;
|
||||
double x,y,z;
|
||||
double cx,cy,cz,r;
|
||||
int imin,imax,jmin,jmax,kmin,kmax;
|
||||
int p,i,j,k,n;
|
||||
//............................................
|
||||
double min_x,min_y,min_z;
|
||||
double distance;
|
||||
//............................................
|
||||
// Lattice spacing for the entire domain
|
||||
// It should generally be true that hx=hy=hz
|
||||
// Otherwise, you will end up with ellipsoids
|
||||
hx = Lx/((Nx-2)*nprocx-1);
|
||||
hy = Ly/((Ny-2)*nprocy-1);
|
||||
hz = Lz/((Nz-2)*nprocz-1);
|
||||
//............................................
|
||||
// Get maximum and minimum for this domain
|
||||
// Halo is included !
|
||||
min_x = double(iproc*(Nx-2)-1)*hx;
|
||||
min_y = double(jproc*(Ny-2)-1)*hy;
|
||||
min_z = double(kproc*(Nz-2)-1)*hz;
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// Pre-initialize Distance
|
||||
for (n=0;n<N;n++){
|
||||
Distance[n]=100.0;
|
||||
}
|
||||
//............................................
|
||||
|
||||
//............................................
|
||||
// .........Loop over the spheres.............
|
||||
for (p=0;p<nspheres;p++){
|
||||
// Get the sphere from the list, map to local min
|
||||
cx = List_cx[p] - min_x;
|
||||
cy = List_cy[p] - min_y;
|
||||
cz = List_cz[p] - min_z;
|
||||
r = List_rad[p];
|
||||
// Check if
|
||||
// Range for this sphere in global indexing
|
||||
imin = int ((cx-2*r)/hx);
|
||||
imax = int ((cx+2*r)/hx)+2;
|
||||
jmin = int ((cy-2*r)/hy);
|
||||
jmax = int ((cy+2*r)/hy)+2;
|
||||
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;
|
||||
// Loop over the domain for this sphere (may be null)
|
||||
for (i=imin;i<imax;i++){
|
||||
for (j=jmin;j<jmax;j++){
|
||||
for (k=kmin;k<kmax;k++){
|
||||
// x,y,z is distance in physical units
|
||||
x = i*hx;
|
||||
y = j*hy;
|
||||
z = k*hz;
|
||||
// if inside sphere, set to zero
|
||||
// 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;
|
||||
// Assign the minimum 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;
|
||||
}
|
||||
|
||||
void WriteLocalSolidID(char *FILENAME, char *ID, int N)
|
||||
{
|
||||
char value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (int n=0; n<N; n++){
|
||||
value = ID[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
void WriteLocalSolidDistance(char *FILENAME, double *Distance, int N)
|
||||
{
|
||||
double value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (int n=0; n<N; n++){
|
||||
value = Distance[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
|
||||
void WriteCheckpoint(const char *FILENAME, const double *cDen, const double *cfq, int Np)
|
||||
{
|
||||
int q,n;
|
||||
double value;
|
||||
ofstream File(FILENAME,ios::binary);
|
||||
for (n=0; n<Np; n++){
|
||||
// Write the two density values
|
||||
value = cDen[n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
value = cDen[Np+n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
// Write the even distributions
|
||||
for (q=0; q<19; q++){
|
||||
value = cfq[q*Np+n];
|
||||
File.write((char*) &value, sizeof(value));
|
||||
}
|
||||
}
|
||||
File.close();
|
||||
|
||||
}
|
||||
|
||||
void ReadCheckpoint(char *FILENAME, double *cDen, double *cfq, int Np)
|
||||
{
|
||||
int q=0, n=0;
|
||||
double value=0;
|
||||
ifstream File(FILENAME,ios::binary);
|
||||
for (n=0; n<Np; n++){
|
||||
// Write the two density values
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cDen[n] = value;
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cDen[Np+n] = value;
|
||||
// Read the even distributions
|
||||
for (q=0; q<19; q++){
|
||||
File.read((char*) &value, sizeof(value));
|
||||
cfq[q*Np+n] = value;
|
||||
}
|
||||
}
|
||||
File.close();
|
||||
}
|
||||
|
||||
void ReadBinaryFile(char *FILENAME, double *Data, int N)
|
||||
{
|
||||
int n;
|
||||
double value;
|
||||
ifstream File(FILENAME,ios::binary);
|
||||
if (File.good()){
|
||||
for (n=0; n<N; n++){
|
||||
// Write the two density values
|
||||
File.read((char*) &value, sizeof(value));
|
||||
Data[n] = value;
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (n=0; n<N; n++) Data[n] = 1.2e-34;
|
||||
}
|
||||
File.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user