From 81764dfd3f497d320f35e6f095cb714a4aeca3f4 Mon Sep 17 00:00:00 2001 From: James McClure Date: Thu, 6 Mar 2014 12:50:13 -0500 Subject: [PATCH] Validated Bubble Test --- cpu/Color.cpp | 25 +- cpu/lb2_Color_wia_mpi.cpp | 322 +++---- example/Bubble/Color.in | 4 +- example/Bubble/Domain.in | 2 +- example/Bubble/ExampleOutput.txt | 46 + tests/TestBubble.cpp | 1340 ++++++++++++------------------ 6 files changed, 726 insertions(+), 1013 deletions(-) create mode 100644 example/Bubble/ExampleOutput.txt diff --git a/cpu/Color.cpp b/cpu/Color.cpp index 0a0f0fba..d1e5b508 100644 --- a/cpu/Color.cpp +++ b/cpu/Color.cpp @@ -756,10 +756,13 @@ extern "C" void dvc_ColorCollide( char *ID, double *disteven, double *distodd, d distodd[8*N+n] = f17; //...Store the Velocity.......................... - Velocity[3*n] = jx; + Velocity[n] = jx; + Velocity[N+n] = jy; + Velocity[2*N+n] = jz; + /* Velocity[3*n] = jx; Velocity[3*n+1] = jy; Velocity[3*n+2] = jz; - //...Store the Color Gradient.................... + */ //...Store the Color Gradient.................... // ColorGrad[3*n] = nx*C; // ColorGrad[3*n+1] = ny*C; // ColorGrad[3*n+2] = nz*C; @@ -1162,9 +1165,9 @@ extern "C" void dvc_ColorCollideOpt( char *ID, double *disteven, double *distodd distodd[7*N+n] = f15; distodd[8*N+n] = f17; //...Store the Velocity.......................... - Velocity[3*n] = jx; - Velocity[3*n+1] = jy; - Velocity[3*n+2] = jz; + Velocity[n] = jx; + Velocity[N+n] = jy; + Velocity[2*N+n] = jz; //*************************************************************** } // check if n is in the solid } // loop over n @@ -1201,9 +1204,9 @@ extern "C" void dvc_MassColorCollideD3Q7(char *ID, double *A_even, double *A_odd ny = ny/C; nz = nz/C; //....Load the flow velocity........... - ux = Velocity[3*n]; - uy = Velocity[3*n+1]; - uz = Velocity[3*n+2]; + ux = Velocity[n]; + uy = Velocity[N+n]; + uz = Velocity[2*N+n]; //........................................................................ // READ THE DISTRIBUTIONS // (read from opposite array due to previous swap operation) @@ -1315,9 +1318,9 @@ extern "C" void dvc_DensityStreamD3Q7(char *ID, double *Den, double *Copy, doubl ny = ny/C; nz = nz/C; //....Load the flow velocity........... - ux = Velocity[3*n]; - uy = Velocity[3*n+1]; - uz = Velocity[3*n+2]; + ux = Velocity[n]; + uy = Velocity[N+n]; + uz = Velocity[2*N+n]; //....Instantiate the density distributions // Generate Equilibrium Distributions and stream // Stationary value - distribution 0 diff --git a/cpu/lb2_Color_wia_mpi.cpp b/cpu/lb2_Color_wia_mpi.cpp index 2ab3385f..2246485b 100644 --- a/cpu/lb2_Color_wia_mpi.cpp +++ b/cpu/lb2_Color_wia_mpi.cpp @@ -1016,10 +1016,11 @@ int main(int argc, char **argv) cDistOdd = new double[9*N]; // data needed to perform CPU-based averaging - double *Vel,*Press; - Vel = new double[3*N]; // fluid velocity - Press = new double[N]; // fluid pressure +// double *Vel; +// Vel = new double[3*N]; // fluid velocity +// Press = new double[N]; // fluid pressure + DoubleArray Press(Nx,Ny,Nz); DoubleArray MeanCurvature(Nx,Ny,Nz); DoubleArray GaussCurvature(Nx,Ny,Nz); DoubleArray SignDist_x(Nx,Ny,Nz); // Gradient of the signed distance @@ -1028,7 +1029,9 @@ int main(int argc, char **argv) DoubleArray Phase_x(Nx,Ny,Nz); // Gradient of the phase indicator field DoubleArray Phase_y(Nx,Ny,Nz); DoubleArray Phase_z(Nx,Ny,Nz); - + DoubleArray Vel_x(Nx,Ny,Nz); // Gradient of the phase indicator field + DoubleArray Vel_y(Nx,Ny,Nz); + DoubleArray Vel_z(Nx,Ny,Nz); /***************************************************************** VARIABLES FOR THE PMMC ALGORITHM ****************************************************************** */ @@ -1276,6 +1279,10 @@ int main(int argc, char **argv) dvc_UnpackValues(dvcRecvList_YZ, recvCount_YZ,recvbuf_YZ, Phi, N); //................................................................................... + if (rank==0 && pBC){ + printf("Setting inlet pressure = %f \n", din); + printf("Setting outlet pressure = %f \n", dout); + } if (pBC && kproc == 0) { dvc_PressureBC_inlet(f_even,f_odd,din,Nx,Ny,Nz,S); dvc_ColorBC_inlet(Phi,Den,A_even,A_odd,B_even,B_odd,Nx,Ny,Nz,S); @@ -1299,8 +1306,10 @@ int main(int argc, char **argv) dvc_Barrier(); dvc_ComputePressureD3Q19(ID,f_even,f_odd,Pressure,Nx,Ny,Nz,S); dvc_CopyToHost(Phase.data,Phi,N*sizeof(double)); - dvc_CopyToHost(Press,Pressure,N*sizeof(double)); - dvc_CopyToHost(Vel,Velocity,3*N*sizeof(double)); + dvc_CopyToHost(Press.data,Pressure,N*sizeof(double)); + dvc_CopyToHost(Vel_x.data,&Velocity[0],N*sizeof(double)); + dvc_CopyToHost(Vel_y.data,&Velocity[N],N*sizeof(double)); + dvc_CopyToHost(Vel_z.data,&Velocity[2*N],N*sizeof(double)); MPI_Barrier(MPI_COMM_WORLD); //........................................................................... @@ -1723,94 +1732,14 @@ int main(int argc, char **argv) //................................................................................... -// ZeroHalo(Den,Nx,Ny,Nz); -// ZeroHalo(Copy,Nx,Ny,Nz); - if (pBC && kproc == 0) { dvc_PressureBC_inlet(f_even,f_odd,din,Nx,Ny,Nz,S); dvc_ColorBC_inlet(Phi,Den,A_even,A_odd,B_even,B_odd,Nx,Ny,Nz,S); - - // Fill the inlet with component a -/* for (k=0; k<1; k++){ - for (j=0;j 0) sum++; - } - } - } - PM.close(); -// printf("File porosity = %f\n", double(sum)/N); -*/ //........................................................................... -// double *SignDist; -// SignDist = new double[N]; + DoubleArray SignDist(Nx,Ny,Nz); -/* //....................................................................... -#ifdef CBUB - // Initializes a constrained bubble test - double BubbleBot = 20.0; // How big to make the NWP bubble - double BubbleTop = 60.0; // How big to make the NWP bubble - double TubeRadius = 15.5; // Radius of the capillary tube + //....................................................................... + + double BubbleRadius = 15.5; // Radius of the capillary tube sum=0; for (k=0;k 0.0){ - id[n] = 2; - sum++; - } - } - } - } - //......................................................... - // If pressure boundary conditions are applied remove solid - if (pBC && kproc == 0){ - for (k=0; k<3; k++){ - for (j=0;j CPU - //........................................................................... - dvc_Barrier(); - dvc_ComputePressureD3Q19(ID,f_even,f_odd,Pressure,Nx,Ny,Nz,S); - dvc_CopyToHost(Phase.data,Phi,N*sizeof(double)); - dvc_CopyToHost(Press,Pressure,N*sizeof(double)); - dvc_CopyToHost(Vel,Velocity,3*N*sizeof(double)); - MPI_Barrier(MPI_COMM_WORLD); - } - if (timestep%10000 == 5){ - //........................................................................... - // Copy the phase indicator field for the later timestep - dvc_Barrier(); - dvc_CopyToHost(Phase_tminus.data,Phi,N*sizeof(double)); - //........................................................................... - // Calculate the time derivative of the phase indicator field - for (n=0; n 0 ){ + // Compute the non-wetting phase volume contribution + if ( Phase(i,j,k) > 0 ) + nwp_volume += 1.0; - // 1-D index for this cube corner - n = i+cube[p][0] + (j+cube[p][1])*Nx + (k+cube[p][2])*Nx*Ny; - - // Compute the non-wetting phase volume contribution - if ( Phase(i+cube[p][0],j+cube[p][1],k+cube[p][2]) > 0 ) - nwp_volume += 0.125; - - // volume averages over the non-wetting phase - if ( Phase(i+cube[p][0],j+cube[p][1],k+cube[p][2]) > 0.9999 ){ - // volume the excludes the interfacial region - vol_n += 0.125; - // pressure - pan += 0.125*Press[n]; - // velocity - van(0) += 0.125*Vel[3*n]; - van(1) += 0.125*Vel[3*n+1]; - van(2) += 0.125*Vel[3*n+2]; - } - - // volume averages over the wetting phase - if ( Phase(i+cube[p][0],j+cube[p][1],k+cube[p][2]) < -0.9999 ){ - // volume the excludes the interfacial region - vol_w += 0.125; - // pressure - paw += 0.125*Press[n]; - // velocity - vaw(0) += 0.125*Vel[3*n]; - vaw(1) += 0.125*Vel[3*n+1]; - vaw(2) += 0.125*Vel[3*n+2]; - } - } + // volume averages over the non-wetting phase + if ( Phase(i,j,k) > 0.99999 ){ + // volume the excludes the interfacial region + vol_n += 1.0; + // pressure + pan += Press.data[n]; + // velocity + van(0) += Vel[3*n]; + van(1) += Vel[3*n+1]; + van(2) += Vel[3*n+2]; } - //........................................................................... - // Construct the interfaces and common curve - pmmc_ConstructLocalCube(SignDist, Phase, solid_isovalue, fluid_isovalue, - nw_pts, nw_tris, values, ns_pts, ns_tris, ws_pts, ws_tris, - local_nws_pts, nws_pts, nws_seg, local_sol_pts, local_sol_tris, - n_local_sol_tris, n_local_sol_pts, n_nw_pts, n_nw_tris, - n_ws_pts, n_ws_tris, n_ns_tris, n_ns_pts, n_local_nws_pts, n_nws_pts, n_nws_seg, - i, j, k, Nx, Ny, Nz); - - // Integrate the contact angle - efawns += pmmc_CubeContactAngle(CubeValues,Values,Phase_x,Phase_y,Phase_z,SignDist_x,SignDist_y,SignDist_z, - local_nws_pts,i,j,k,n_local_nws_pts); - - // Integrate the mean curvature - Jwn += pmmc_CubeSurfaceInterpValue(CubeValues,MeanCurvature,nw_pts,nw_tris,Values,i,j,k,n_nw_pts,n_nw_tris); - - pmmc_InterfaceSpeed(dPdt, Phase_x, Phase_y, Phase_z, CubeValues, nw_pts, nw_tris, - NormalVector, InterfaceSpeed, vawn, i, j, k, n_nw_pts, n_nw_tris); - - //........................................................................... - // Compute the Interfacial Areas, Common Line length - /* awn += pmmc_CubeSurfaceArea(nw_pts,nw_tris,n_nw_tris); - ans += pmmc_CubeSurfaceArea(ns_pts,ns_tris,n_ns_tris); - aws += pmmc_CubeSurfaceArea(ws_pts,ws_tris,n_ws_tris); - */ - As += pmmc_CubeSurfaceArea(local_sol_pts,local_sol_tris,n_local_sol_tris); - - // Compute the surface orientation and the interfacial area - awn += pmmc_CubeSurfaceOrientation(Gwn,nw_pts,nw_tris,n_nw_tris); - ans += pmmc_CubeSurfaceOrientation(Gns,ns_pts,ns_tris,n_ns_tris); - aws += pmmc_CubeSurfaceOrientation(Gws,ws_pts,ws_tris,n_ws_tris); - lwns += pmmc_CubeCurveLength(local_nws_pts,n_local_nws_pts); - //........................................................................... - } - //........................................................................... - MPI_Barrier(MPI_COMM_WORLD); - MPI_Allreduce(&nwp_volume,&nwp_volume_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&awn,&awn_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&ans,&ans_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&aws,&aws_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&lwns,&lwns_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&As,&As_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&Jwn,&Jwn_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&efawns,&efawns_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - // Phase averages - MPI_Allreduce(&vol_w,&vol_w_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&vol_n,&vol_n_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&paw,&paw_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&pan,&pan_global,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&vaw(0),&vaw_global(0),3,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&van(0),&van_global(0),3,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&vawn(0),&vawn_global(0),3,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&Gwn(0),&Gwn_global(0),6,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&Gns(0),&Gns_global(0),6,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&Gws(0),&Gws_global(0),6,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Barrier(MPI_COMM_WORLD); - //......................................................................... - // Compute the change in the total surface energy based on the defined interval - // See McClure, Prins and Miller (2013) - //......................................................................... - dAwn += awn_global; - dAns += ans_global; - dEs = 6.01603*alpha*(dAwn + 1.05332*Ps*dAns); - dAwn = -awn_global; // Get ready for the next analysis interval - dAns = -ans_global; - - // Normalize the phase averages - // (density of both components = 1.0) - paw_global = paw_global / vol_w_global; - vaw_global(0) = vaw_global(0) / vol_w_global; - vaw_global(1) = vaw_global(1) / vol_w_global; - vaw_global(2) = vaw_global(2) / vol_w_global; - pan_global = pan_global / vol_n_global; - van_global(0) = van_global(0) / vol_n_global; - van_global(1) = van_global(1) / vol_n_global; - van_global(2) = van_global(2) / vol_n_global; - - // Normalize surface averages by the interfacial area - Jwn_global /= awn_global; - efawns_global /= lwns_global; - - if (awn_global > 0.0) for (i=0; i<3; i++) vawn_global(i) /= awn_global; - if (awn_global > 0.0) for (i=0; i<6; i++) Gwn_global(i) /= awn_global; - if (ans_global > 0.0) for (i=0; i<6; i++) Gns_global(i) /= ans_global; - if (aws_global > 0.0) for (i=0; i<6; i++) Gws_global(i) /= aws_global; - - sat_w = 1.0 - nwp_volume_global*iVol_global/porosity; - // Compute the specific interfacial areas and common line length (per unit volume) - awn_global = awn_global*iVol_global; - ans_global = ans_global*iVol_global; - aws_global = aws_global*iVol_global; - lwns_global = lwns_global*iVol_global; - dEs = dEs*iVol_global; - - //......................................................................... - if (rank==0){ - /* printf("-------------------------------- \n"); - printf("Timestep = %i \n", timestep); - printf("NWP volume = %f \n", nwp_volume_global); - printf("Area wn = %f \n", awn_global); - printf("Area ns = %f \n", ans_global); - printf("Area ws = %f \n", aws_global); - printf("Change in surface energy = %f \n", dEs); - printf("-------------------------------- \n"); - - printf("%i %.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g \n", - timestep,dEs,sat_w, - awn_global,ans_global,aws_global, lwns_global, p_w_global, p_n_global, - vx_w_global, vy_w_global, vz_w_global, - vx_n_global, vy_n_global, vz_n_global); - */ - printf("%.5g ",BubbleRadius); // bubble radius - printf("%.5g %.5g %.5g ",sat_w,paw_global,pan_global); // saturation and pressure - printf("%.5g ",awn_global); // interfacial area - printf("%.5g ",Jwn_global); // curvature of wn interface - printf("%.5g %.5g %.5g %.5g %.5g %.5g \n", - Gwn_global(0),Gwn_global(1),Gwn_global(2),Gwn_global(3),Gwn_global(4),Gwn_global(5)); // orientation of wn interface + // volume averages over the wetting phase + if ( Phase(i,j,k) < -0.99999 ){ + // volume the excludes the interfacial region + vol_w += 1.0; + // pressure + paw += Press.data[n]; + // velocity + vaw(0) += Vel[3*n]; + vaw(1) += Vel[3*n+1]; + vaw(2) += Vel[3*n+2]; + } + } } } + + for (c=0;c 0.0) for (i=0; i<3; i++) vawn_global(i) /= awn_global; + if (awn_global > 0.0) for (i=0; i<6; i++) Gwn_global(i) /= awn_global; + if (ans_global > 0.0) for (i=0; i<6; i++) Gns_global(i) /= ans_global; + if (aws_global > 0.0) for (i=0; i<6; i++) Gws_global(i) /= aws_global; + + sat_w = 1.0 - nwp_volume_global*iVol_global/porosity; + // Compute the specific interfacial areas and common line length (per unit volume) + awn_global = awn_global*iVol_global; + ans_global = ans_global*iVol_global; + aws_global = aws_global*iVol_global; + lwns_global = lwns_global*iVol_global; + dEs = dEs*iVol_global; + + //......................................................................... + if (rank==0){ + printf("%.5g ",BubbleRadius); // bubble radius + printf("%.5g %.5g ",paw_global,pan_global); // saturation and pressure + printf("%.5g ",awn_global); // interfacial area + printf("%.5g ",Jwn_global); // curvature of wn interface + printf("%.5g %.5g %.5g %.5g %.5g %.5g \n", + Gwn_global(0),Gwn_global(1),Gwn_global(2),Gwn_global(3),Gwn_global(4),Gwn_global(5)); // orientation of wn interface + } + } //************************************************************************/ dvc_Barrier(); MPI_Barrier(MPI_COMM_WORLD); - + stoptime = MPI_Wtime(); + if (rank==0) printf("-------------------------------------------------------------------\n"); + // Compute the walltime per timestep + cputime = (stoptime - starttime)/timestep; + // Performance obtained from each node + double MLUPS = double(Nx*Ny*Nz)/cputime/1000000; + + if (rank==0) printf("********************************************************\n"); + if (rank==0) printf("CPU time = %f \n", cputime); + if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS); + MLUPS *= nprocs; + if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS); + if (rank==0) printf("********************************************************\n"); + //************************************************************************/ // Write out the phase indicator field //************************************************************************/ + sprintf(LocalRankFilename,"%s%s","Phase.",LocalRankString); // printf("Local File Name = %s \n",LocalRankFilename); // dvc_CopyToHost(Phase.data,Phi,N*sizeof(double)); - - //!!!!!!!!DEBUG HERE!!!!!!!!!!!!! -/* dvc_InitDenColorDistance(ID, Den, Phi, SignDist.data, das, dbs, beta, xIntPos, Nx, Ny, Nz, S); - dvc_InitD3Q7(ID, A_even, A_odd, &Den[0], Nx, Ny, Nz, S); - dvc_InitD3Q7(ID, B_even, B_odd, &Den[N], Nx, Ny, Nz, S); - dvc_ComputeDensityD3Q7(ID, A_even, A_odd, &Den[0], Nx, Ny, Nz, S); - dvc_ComputeDensityD3Q7(ID, B_even, B_odd, &Den[N], Nx, Ny, Nz, S); - dvc_ComputePhi(ID, Phi, Den, N, S); - - if (pBC && kproc == 0) { - dvc_PressureBC_inlet(f_even,f_odd,din,Nx,Ny,Nz,S); - - // Fill the inlet with component a - for (k=0; k<1; k++){ - for (j=0;j