868
/****fluid contents: begin****/
874
void NeighborTable<T>::initiateFluid(
891
m_Bw=Bw;m_Bp=Bp;m_Mu=Mu;m_adjust=alpha;m_flowrate=flowrate;m_pressure=pressure;m_inflow=inflow;m_outflow=outflow;
892
m_xcell=nx;m_ycell=ny;m_zcell=nz;
893
m_global_cellidx=nx_min;m_global_cellidy=ny_min;m_global_cellidz=nz_min;
894
m_xside=m_dim*double(m_xsize-2)/double(nx-2);
895
m_yside=m_dim*double(m_ysize-2)/double(ny-2);
896
m_zside=m_dim*double(m_zsize-2)/double(nz-2);
898
cout << "neighbor table info: "<<endl;
899
cout << " Bw=" << m_Bw << " Bp=" <<m_Bp << " Mu=" << m_Mu << " m_adjust=" << m_adjust << endl;
900
cout << " m_flowrate=" << m_flowrate << " m_pressure=" <<m_pressure << " m_inflow=" << m_inflow << " m_outflow=" << m_outflow<<endl;
901
cout << " m_xcell=" << m_xcell <<" m_ycell="<<m_ycell<<" m_zcell="<<m_zcell<< endl;
902
cout << " m_xside=" << m_xside <<" m_yside="<<m_yside<<" m_zside="<<m_zside<< endl;
904
m_cellarray.resize(m_xcell*m_ycell*m_zcell);
905
m_cells.resize(m_xcell*m_ycell*m_zcell);
906
for(int i=0;i<m_xcell;i++){
907
for(int j=0;j<m_ycell;j++){
908
for(int k=0;k<m_zcell;k++){
909
double global_x=m_min_corner.X()+m_dim+(i-0.5)*m_xside;
910
double global_y=m_min_corner.Y()+m_dim+(j-0.5)*m_yside;
911
double global_z=m_min_corner.Z()+m_dim+(k-0.5)*m_zside;
912
Vec3 global_pos=Vec3(global_x,global_y,global_z);
913
int idx=cellindex(i,j,k);
914
m_cells[idx].setPos(global_pos);
915
m_cells[idx].setSize(Vec3(m_xside,m_yside,m_zside));
916
m_cells[idx].setIndex(Vec3(m_global_cellidx+i,m_global_cellidy+j,m_global_cellidz+k));
925
Create a full list of pair of particle and cell and return handle to it
928
T_Handle<typename NeighborTable<T>::particlecelllist> NeighborTable<T>::getParticleCellList()
930
T_Handle<typename NeighborTable<T>::particlecelllist> nlist=new typename NeighborTable<T>::particlecelllist;
933
for(typename list<T>::iterator iter=m_list.begin();
936
int idx=cellindex(iter->getPos());
938
nlist->push_back(make_pair(&(*iter),&m_cells[idx]));
946
Create a new list of pair of particle and cell and return handle to it
949
T_Handle<typename NeighborTable<T>::particlecelllist> NeighborTable<T>::getNewParticleCellList()
951
T_Handle<typename NeighborTable<T>::particlecelllist> nlist=new typename NeighborTable<T>::particlecelllist;
952
for(typename list<T>::iterator iter=m_list.begin();
955
if(iter->isFlagged()){
956
int idx=cellindex(iter->getPos());
958
nlist->push_back(make_pair(&(*iter),&m_cells[idx]));
967
Calculate initial fluid cell porosity using measurement sphere method
971
void NeighborTable<T>::calPorositySphere0()
977
double r1=(m_xside+m_yside+m_zside)/6.0;
978
double cellVolume=3.1415926*4.0/3.0*r1*r1*r1;
979
for(int i=1;i<m_xcell-1;i++){
980
for(int j=1;j<m_ycell-1;j++){
981
for(int k=1;k<m_zcell-1;k++){
982
int idx=cellindex(i,j,k);
983
Vec3 pos=m_cells[idx].getPos();
985
if(i==1||i==m_xcell-2||j==1||j==m_ycell-2||k==1||k==m_zcell-2){
986
int ix=int(floor((pos.X()-m_p0_global.X())/m_dim))-m_global_idx;
987
int iy=int(floor((pos.Y()-m_p0_global.Y())/m_dim))-m_global_idy;
988
int iz=int(floor((pos.Z()-m_p0_global.Z())/m_dim))-m_global_idz;
989
if((ix<1)||(ix>m_xsize-2)||(iy<1)||(iy>m_ysize-2)||(iz<1)||(iz>m_zsize-2)){
990
cout<<"neighbor table size does not match fluid cell size, program aborted!"<<endl;
994
double gridVolume=3.1415926*4.0/3.0*r*r*r;
995
int ixmin=ix-1; int ixmax=ix+1;
996
int iymin=iy-1; int iymax=iy+1;
997
int izmin=iz-1; int izmax=iz+1;
1000
for(int iix=ixmin;iix<=ixmax;iix++){
1001
for(int iiy=iymin;iiy<=iymax;iiy++){
1002
for(int iiz=izmin;iiz<=izmax;iiz++){
1003
if((iix>=1)&&(iix<=m_xsize-2)&&(iiy>=1)&&(iiy<=m_ysize-2)&&(iiz>=1)&&(iiz<=m_zsize-2)){
1004
double global_x=m_p0_global.X()+(iix+m_global_idx+0.5)*m_dim;
1005
double global_y=m_p0_global.Y()+(iiy+m_global_idy+0.5)*m_dim;
1006
double global_z=m_p0_global.Z()+(iiz+m_global_idz+0.5)*m_dim;
1007
Vec3 nt_pos=Vec3(global_x,global_y,global_z);
1008
int xmin=iix-1; int xmax=iix+1;
1009
int ymin=iiy-1; int ymax=iiy+1;
1010
int zmin=iiz-1; int zmax=iiz+1;
1012
for(int x=xmin;x<=xmax;x++){
1013
for(int y=ymin;y<=ymax;y++){
1014
for(int z=zmin;z<=zmax;z++){
1015
int nt_idx=index(x,y,z);
1016
for(typename pointtype::iterator iter=m_array[nt_idx].begin();
1017
iter!=m_array[nt_idx].end();
1019
double r2=(*iter)->getRad();
1020
double d=((*iter)->getPos()-nt_pos).norm();
1022
ivolume+=3.1415926*4.0/3.0*r2*r2*r2;
1024
ivolume+=3.1415926/12.0/d*(r+r2-d)*(r+r2-d)*(d*d+2.0*d*(r+r2)-3.0*(r-r2)*(r-r2));
1030
double phi=1.0-ivolume/gridVolume;
1031
if(phi<=0){phi=0.00001;};
1032
if(phi>=1){phi=0.99999;};
1040
double newPhi=iPhi/double(inumber);
1041
if(newPhi<=0.0){newPhi=0.00001;};
1042
if(newPhi>=1.0){newPhi=0.99999;};
1043
m_cells[idx].setPhi(newPhi);
1044
m_cells[idx].setnewPhi(newPhi);
1045
m_cells[idx].seteffPhi(newPhi);
1047
int xmin=i-1; int xmax=i+1;
1048
int ymin=j-1; int ymax=j+1;
1049
int zmin=k-1; int zmax=k+1;
1050
for(int x=xmin;x<=xmax;x++){
1051
for(int y=ymin;y<=ymax;y++){
1052
for(int z=zmin;z<=zmax;z++){
1053
int index=cellindex(x,y,z);
1054
for(typename pointtype::iterator iter=m_cellarray[index].begin();
1055
iter!=m_cellarray[index].end();
1057
double r2=(*iter)->getRad();
1058
double d=((*iter)->getPos()-pos).norm();
1060
volume+=3.1415926*4.0/3.0*r2*r2*r2;
1062
volume+=3.1415926/12.0/d*(r1+r2-d)*(r1+r2-d)*(d*d+2.0*d*(r1+r2)-3.0*(r1-r2)*(r1-r2));
1068
m_cells[idx].setVolume(volume);
1069
double newPhi=1.0-m_cells[idx].getVolume()/cellVolume;
1070
if(newPhi<=0.0){newPhi=0.00001;};
1071
if(newPhi>=1.0){newPhi=0.99999;};
1072
m_cells[idx].setPhi(newPhi);
1073
m_cells[idx].setnewPhi(newPhi);
1074
m_cells[idx].seteffPhi(newPhi);
1077
for(typename pointtype::iterator iter=m_cellarray[idx].begin();
1078
iter!=m_cellarray[idx].end();
1080
double r=(*iter)->getRad();
1086
if(num_p!=0){num_cells++;};
1092
double meanD=tot_d/double(number);
1093
double tot_vp=4.0/3.0*3.1415926*tot_r3;
1094
double meanPhi=1.0-tot_vp/double(num_cells)/(m_xside*m_yside*m_zside);
1095
meanK=pow(meanD,2.0)/180.0*pow(meanPhi,3.0)/pow(1.0-meanPhi,2.0);
1099
for(int i=1;i<m_xcell-1;i++){
1100
for(int j=1;j<m_ycell-1;j++){
1101
for(int k=1;k<m_zcell-1;k++){
1102
int idx=cellindex(i,j,k);
1103
double cell_totd=0.0;
1106
for(typename pointtype::iterator iter=m_cellarray[idx].begin();
1107
iter!=m_cellarray[idx].end();
1109
double r=(*iter)->getRad();
1114
double D=cell_totd/double(p_in_cell);
1115
m_cells[idx].setD(D);//mean diameter of particles
1116
double Phi=m_cells[idx].getnewPhi();
1117
newK=pow(D,2.0)/180.0*pow(Phi,3.0)/pow(1.0-Phi,2.0);
1118
if(newK>meanK){newK=meanK;};
1120
m_cells[idx].setD(0);
1123
m_cells[idx].setK(newK);
1124
m_cells[idx].seteffK(newK);
1125
double newBf=1.0/((1.0-m_cells[idx].getnewPhi())/m_Bp+m_cells[idx].getnewPhi()/m_Bw);
1126
m_cells[idx].setBf(newBf);
1127
m_cells[idx].seteffBf(newBf);
1128
m_cells[idx].setMu(m_Mu);
1136
Calculate the fluid cell porosity using measurement sphere method
1139
template<typename T>
1140
void NeighborTable<T>::calPorositySphere()
1142
double r1=(m_xside+m_yside+m_zside)/6.0;
1143
double cellVolume=3.1415926*4.0/3.0*r1*r1*r1;
1145
for(int i=1;i<m_xcell-1;i++){
1146
for(int j=1;j<m_ycell-1;j++){
1147
for(int k=1;k<m_zcell-1;k++){
1148
int idx=cellindex(i,j,k);
1149
Vec3 pos=m_cells[idx].getPos();
1152
if(i==1||i==m_xcell-2||j==1||j==m_ycell-2||k==1||k==m_zcell-2){
1153
int ix=int(floor((pos.X()-m_p0_global.X())/m_dim))-m_global_idx;
1154
int iy=int(floor((pos.Y()-m_p0_global.Y())/m_dim))-m_global_idy;
1155
int iz=int(floor((pos.Z()-m_p0_global.Z())/m_dim))-m_global_idz;
1156
if((ix<1)||(ix>m_xsize-2)||(iy<1)||(iy>m_ysize-2)||(iz<1)||(iz>m_zsize-2)){
1157
cerr<<"neighbor table size does not match fluid cell size, program aborted!"<<endl;
1161
double gridVolume=3.1415926*4.0/3.0*r*r*r;
1162
int ixmin=ix-1; int ixmax=ix+1;
1163
int iymin=iy-1; int iymax=iy+1;
1164
int izmin=iz-1; int izmax=iz+1;
1167
for(int iix=ixmin;iix<=ixmax;iix++){
1168
for(int iiy=iymin;iiy<=iymax;iiy++){
1169
for(int iiz=izmin;iiz<=izmax;iiz++){
1170
if((iix>=1)&&(iix<=m_xsize-2)&&(iiy>=1)&&(iiy<=m_ysize-2)&&(iiz>=1)&&(iiz<=m_zsize-2)){
1171
double global_x=m_p0_global.X()+(iix+m_global_idx+0.5)*m_dim;
1172
double global_y=m_p0_global.Y()+(iiy+m_global_idy+0.5)*m_dim;
1173
double global_z=m_p0_global.Z()+(iiz+m_global_idz+0.5)*m_dim;
1174
Vec3 nt_pos=Vec3(global_x,global_y,global_z);
1175
int xmin=iix-1; int xmax=iix+1;
1176
int ymin=iiy-1; int ymax=iiy+1;
1177
int zmin=iiz-1; int zmax=iiz+1;
1179
for(int x=xmin;x<=xmax;x++){
1180
for(int y=ymin;y<=ymax;y++){
1181
for(int z=zmin;z<=zmax;z++){
1182
int nt_idx=index(x,y,z);
1183
for(typename pointtype::iterator iter=m_array[nt_idx].begin();
1184
iter!=m_array[nt_idx].end();
1186
double r2=(*iter)->getRad();
1187
double d=((*iter)->getPos()-nt_pos).norm();
1189
ivolume+=3.1415926*4.0/3.0*r2*r2*r2;
1191
ivolume+=3.1415926/12.0/d*(r+r2-d)*(r+r2-d)*(d*d+2.0*d*(r+r2)-3.0*(r-r2)*(r-r2));
1197
double phi=1.0-ivolume/gridVolume;
1198
if(phi<=0){phi=0.00001;};
1199
if(phi>=1){phi=0.99999;};
1206
m_cells[idx].setPhi(m_cells[idx].getnewPhi());//porosity
1207
m_cells[idx].setnewPhi(iPhi/double(inumber));//new porosity
1208
if(m_cells[idx].getnewPhi()<=0){m_cells[idx].setnewPhi(0.00001);};
1209
if(m_cells[idx].getnewPhi()>=1){m_cells[idx].setnewPhi(0.99999);};
1211
int xmin=i-1; int xmax=i+1;
1212
int ymin=j-1; int ymax=j+1;
1213
int zmin=k-1; int zmax=k+1;
1214
for(int x=xmin;x<=xmax;x++){
1215
for(int y=ymin;y<=ymax;y++){
1216
for(int z=zmin;z<=zmax;z++){
1217
int index=cellindex(x,y,z);
1218
for(typename pointtype::iterator iter=m_cellarray[index].begin();
1219
iter!=m_cellarray[index].end();
1221
double r2=(*iter)->getRad();
1222
double d=((*iter)->getPos()-pos).norm();
1224
volume+=3.1415926*4.0/3.0*r2*r2*r2;
1226
volume+=3.1415926/12.0/d*(r1+r2-d)*(r1+r2-d)*(d*d+2.0*d*(r1+r2)-3.0*(r1-r2)*(r1-r2));
1232
m_cells[idx].setVolume(volume);
1233
m_cells[idx].setPhi(m_cells[idx].getnewPhi());//porosity
1234
m_cells[idx].setnewPhi(1.0-m_cells[idx].getVolume()/cellVolume);//new porosity
1235
if(m_cells[idx].getnewPhi()<=0){m_cells[idx].setnewPhi(0.00001);};
1236
if(m_cells[idx].getnewPhi()>=1){m_cells[idx].setnewPhi(0.99999);};
1239
m_cells[idx].seteffPhi((1.0-m_adjust)*m_cells[idx].getPhi()+m_adjust*m_cells[idx].getnewPhi());//effective porosity
1247
Update fluid cell: m_D, m_Vp, m_K, m_Bf;
1249
template<typename T>
1250
void NeighborTable<T>::updateFluidcells(){
1255
for(int i=1;i<m_xcell-1;i++){
1256
for(int j=1;j<m_ycell-1;j++){
1257
for(int k=1;k<m_zcell-1;k++){
1258
int idx=cellindex(i,j,k);
1260
for(typename pointtype::iterator iter=m_cellarray[idx].begin();
1261
iter!=m_cellarray[idx].end();
1263
double r=(*iter)->getRad();
1269
if(num_p!=0){num_cells++;};
1276
double meanD=tot_d/double(number);
1277
double tot_vp=4.0/3.0*3.1415926*tot_r3;
1278
double meanPhi=1.0-tot_vp/double(num_cells)/(m_xside*m_yside*m_zside);
1279
meanK=pow(meanD,2.0)/180.0*pow(meanPhi,3.0)/pow(1.0-meanPhi,2.0);
1283
for(int i=1;i<m_xcell-1;i++){
1284
for(int j=1;j<m_ycell-1;j++){
1285
for(int k=1;k<m_zcell-1;k++){
1286
int idx=cellindex(i,j,k);
1287
double cell_totd=0.0;
1291
for(typename pointtype::iterator iter=m_cellarray[idx].begin();
1292
iter!=m_cellarray[idx].end();
1294
double r=(*iter)->getRad();
1299
double D=cell_totd/double(p_in_cell);
1300
m_cells[idx].setD(D);//mean diameter of particles
1301
Vec3 Vp=tot_vel/double(p_in_cell);
1302
m_cells[idx].setVp(Vp);//mean particle velocity
1303
double Phi=m_cells[idx].getnewPhi();
1304
newK=pow(D,2.0)/180.0*pow(Phi,3.0)/pow(1.0-Phi,2.0);
1305
if(newK>meanK){newK=meanK;};
1307
m_cells[idx].setD(0);
1308
m_cells[idx].setVp(Vec3(0.0,0.0,0.0));
1311
m_cells[idx].seteffK((1.0-m_adjust)*m_cells[idx].getK()+m_adjust*newK); //effective permeability
1312
m_cells[idx].setK(newK);//updated permeability
1313
double Phi=m_cells[idx].getnewPhi();
1314
double newBf=1.0/((1.0-Phi)/m_Bp+Phi/m_Bw);
1315
m_cells[idx].seteffBf((1.0-m_adjust)*m_cells[idx].getBf()+m_adjust*newBf);//effective bulk mudulus
1316
m_cells[idx].setBf(newBf);//updated bulk mudulus
1317
m_cells[idx].setMu(m_Mu);
1325
Calculate coefficients for linear equations
1327
template<typename T>
1328
void NeighborTable<T>::calCoeffi(double timestep,int nt) {
1330
double A_w, A_e, A_n, A_s, A_u, A_d, A_c, B_w, B_e, B_n, B_s, B_u, B_d, B_c;
1331
double co_w,co_e,co_n,co_s,co_u, co_d, co_c,co_b;
1332
int idx,idx_w,idx_e,idx_s,idx_n,idx_u,idx_d;
1333
double K,Kw,Ke,Ks,Kn,Ku,Kd;
1334
double P,Pw,Pe,Ps,Pn,Pu,Pd;
1336
double V=m_xside*m_yside*m_zside;
1337
for(int ix=1;ix<m_xcell-1;ix++){
1338
for(int iy=1;iy<m_ycell-1;iy++){
1339
for(int iz=1;iz<m_zcell-1;iz++){
1340
idx=cellindex(ix,iy,iz);
1341
idx_w=cellindex(ix-1,iy,iz); idx_e=cellindex(ix+1,iy,iz); idx_n=cellindex(ix,iy-1,iz);
1342
idx_s=cellindex(ix,iy+1,iz); idx_d=cellindex(ix,iy,iz-1); idx_u=cellindex(ix,iy,iz+1);
1343
K=m_cells[idx].geteffK();
1344
Kw=m_cells[idx_w].geteffK(); Ke=m_cells[idx_e].geteffK(); Ks=m_cells[idx_s].geteffK();
1345
Kn=m_cells[idx_n].geteffK(); Ku=m_cells[idx_u].geteffK(); Kd=m_cells[idx_d].geteffK();
1346
P=m_cells[idx].getdisP();
1347
Pw=m_cells[idx_w].getdisP(); Pe=m_cells[idx_e].getdisP(); Ps=m_cells[idx_s].getdisP();
1348
Pn=m_cells[idx_n].getdisP(); Pu=m_cells[idx_u].getdisP(); Pd=m_cells[idx_d].getdisP();
1349
double Bf=m_cells[idx].geteffBf();
1350
double Phi=m_cells[idx].geteffPhi();
1351
double dV=(m_cells[idx].getPhi()-m_cells[idx].getnewPhi())/nt; //pore volume change
1352
double dP=Bf*dV; //pressure change
1353
if(fabs(m_min_corner.X()+m_dim-m_p0_global.X())<1e-6 && ix==1){ //cell located at west boundary
1354
if(m_inflow.X()==1 || m_inflow.X()==2){ //inlet
1357
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_xside;}
1358
else{flowrate=m_flowrate;};
1359
B_w=Bf/V/Phi*flowrate*timestep*m_yside*m_zside;
1360
} else if(m_outflow.X()==-1 || m_outflow.X()==2){ //outlet
1361
A_w=K*m_xside*timestep/m_Mu;
1364
} else { //closed boundary
1367
} else{ //cell located in inner area
1368
A_w=0.5*(K+Kw)*timestep*m_yside*m_zside/m_xside/m_Mu;
1370
B_w=(1.0-m_adjust)*co_w*Pw;
1373
if(fabs(m_max_corner.X()-m_dim-m_pmax_global.X())<1e-6 && ix==(m_xcell-2)){ //cell located at east boundary
1374
if(m_inflow.X()==-1 || m_inflow.X()==2){ //inlet
1377
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_xside;}
1378
else{flowrate=m_flowrate;};
1379
B_e=Bf/V/Phi*flowrate*timestep*m_yside*m_zside;
1380
} else if(m_outflow.X()==1 || m_outflow.X()==2){ //outlet
1381
A_e=K*m_xside*timestep/m_Mu;
1384
} else { //closed boundary
1387
} else{ //cell located in inner area
1388
A_e=0.5*(K+Ke)*timestep*m_yside*m_zside/m_xside/m_Mu;
1390
B_e=(1.0-m_adjust)*co_e*Pe;
1393
if(fabs(m_min_corner.Y()+m_dim-m_p0_global.Y())<1e-6 && iy==1){ //cell located at north boundary
1394
if(m_inflow.Y()==1 || m_inflow.Y()==2){ //inlet
1397
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_yside;}
1398
else{flowrate=m_flowrate;};
1399
B_n=Bf/V/Phi*flowrate*timestep*m_xside*m_zside;
1400
} else if(m_outflow.Y()==-1 || m_outflow.Y()==2){ //outlet
1401
A_n=K*m_yside*timestep/m_Mu;
1404
} else { //closed boundary
1407
} else{ //cell located in inner area
1408
A_n=0.5*(K+Kn)*timestep*m_xside*m_zside/m_yside/m_Mu;
1410
B_n=(1.0-m_adjust)*co_n*Pn;
1413
if(fabs(m_max_corner.Y()-m_dim-m_pmax_global.Y())<1e-6 && iy==(m_ycell-2)){ //cell located at south boundary
1414
if(m_inflow.Y()==-1 || m_inflow.Y()==2){ //inlet
1417
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_yside;}
1418
else{flowrate=m_flowrate;};
1419
B_s=Bf/V/Phi*flowrate*timestep*m_xside*m_zside;
1420
} else if(m_outflow.Y()==1 || m_outflow.Y()==2){ //outlet
1421
A_s=K*m_yside*timestep/m_Mu;
1424
} else { //closed boundary
1427
} else{ //cell located in inner area
1428
A_s=0.5*(K+Ks)*timestep*m_xside*m_zside/m_yside/m_Mu;
1430
B_s=(1.0-m_adjust)*co_s*Ps;
1433
if(fabs(m_min_corner.Z()+m_dim-m_p0_global.Z())<1e-6 && iz==1){ //cell located at down/lower boundary
1434
if(m_inflow.Z()==1 || m_inflow.Z()==2){ //inlet
1437
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_zside;}
1438
else{flowrate=m_flowrate;};
1439
B_d=Bf/V/Phi*flowrate*timestep*m_xside*m_yside;
1440
} else if(m_outflow.Z()==-1 || m_outflow.Z()==2){ //outlet
1441
A_d=K*m_zside*timestep/m_Mu;
1444
} else { //closed boundary
1447
} else{ //cell located in inner area
1448
A_d=0.5*(K+Kd)*timestep*m_xside*m_yside/m_zside/m_Mu;
1450
B_d=(1.0-m_adjust)*co_d*Pd;
1453
if(fabs(m_max_corner.Z()-m_dim-m_pmax_global.Z())<1e-6 && iz==(m_zcell-2)){ //cell located at upper boundary
1454
if(m_inflow.Z()==-1 || m_inflow.Z()==2){ //inlet
1457
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_zside;}
1458
else{flowrate=m_flowrate;};
1459
B_u=Bf/V/Phi*flowrate*timestep*m_xside*m_yside;
1460
} else if(m_outflow.Z()==1 || m_outflow.Z()==2){ //outlet
1461
A_u=K*m_zside*timestep/m_Mu;
1464
} else { //closed boundary
1467
} else{ //cell located in inner area
1468
A_u=0.5*(K+Ku)*timestep*m_xside*m_yside/m_zside/m_Mu;
1470
B_u=(1.0-m_adjust)*co_u*Pu;
1472
A_c=-(A_w+A_e+A_n+A_s+A_d+A_u);
1473
co_c=m_adjust*Bf/V/Phi*A_c-1.0;
1474
B_c=((1.0-m_adjust)*A_c*Bf/V/Phi+1.0)*P; //coefficent for central cell
1475
co_b=-(B_w+B_e+B_n+B_s+B_d+B_u+B_c+dP); //Constant
1476
m_cells[idx].setc_W(m_adjust*co_w);
1477
m_cells[idx].setc_E(m_adjust*co_e);
1478
m_cells[idx].setc_N(m_adjust*co_n);
1479
m_cells[idx].setc_S(m_adjust*co_s);
1480
m_cells[idx].setc_D(m_adjust*co_d);
1481
m_cells[idx].setc_U(m_adjust*co_u);
1482
m_cells[idx].setc_C(co_c);
1483
m_cells[idx].setc_B(co_b);
1491
setting distributed pore pressures;
1493
template<typename T>
1494
void NeighborTable<T>::setPressure(vector<pair<Vec3,double> > pressure)
1496
for(int ix=1;ix<m_xcell-1;ix++){
1497
for(int iy=1;iy<m_ycell-1;iy++){
1498
for(int iz=1;iz<m_zcell-1;iz++){
1499
int idx=cellindex(ix,iy,iz);
1500
Vec3 global_index=m_cells[idx].getIndex();
1501
for(vector<pair<Vec3,double> >::iterator iter=pressure.begin();
1502
iter!=pressure.end();
1504
if(global_index==iter->first){
1507
m_cells[idx].setdisP(0);
1509
m_cells[idx].setdisP(iter->second);
1522
calculate fluid velocity and pressure gradient
1524
template<typename T>
1525
void NeighborTable<T>::calVelocity()
1527
int idx,idx_w,idx_e,idx_s,idx_n,idx_u,idx_d;
1528
double K,Kw,Ke,Ks,Kn,Ku,Kd;
1529
double P,Pw,Pe,Ps,Pn,Pu,Pd;
1530
double Vw,Ve,Vn,Vs,Vd,Vu;
1533
for(int ix=1;ix<m_xcell-1;ix++){
1534
for(int iy=1;iy<m_ycell-1;iy++){
1535
for(int iz=1;iz<m_zcell-1;iz++){
1536
idx=cellindex(ix,iy,iz);
1537
idx_w=cellindex(ix-1,iy,iz); idx_e=cellindex(ix+1,iy,iz); idx_n=cellindex(ix,iy-1,iz);
1538
idx_s=cellindex(ix,iy+1,iz); idx_d=cellindex(ix,iy,iz-1); idx_u=cellindex(ix,iy,iz+1);
1539
K=m_cells[idx].getK();
1540
Kw=m_cells[idx_w].getK(); Ke=m_cells[idx_e].getK(); Ks=m_cells[idx_s].getK();
1541
Kn=m_cells[idx_n].getK(); Ku=m_cells[idx_u].getK(); Kd=m_cells[idx_d].getK();
1542
P=m_cells[idx].getdisP();
1543
Pw=m_cells[idx_w].getdisP(); Pe=m_cells[idx_e].getdisP(); Ps=m_cells[idx_s].getdisP();
1544
Pn=m_cells[idx_n].getdisP(); Pu=m_cells[idx_u].getdisP(); Pd=m_cells[idx_d].getdisP();
1545
double Phi=m_cells[idx].getnewPhi();
1546
//calculate fluid velocity:
1547
if(fabs(m_min_corner.X()+m_dim-m_p0_global.X())<1e-6 && ix==1){ //cell located at west boundary
1548
if(m_inflow.X()==1 || m_inflow.X()==2){
1549
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_xside;}
1550
else{flowrate=m_flowrate;};
1551
Vw=flowrate/Phi;Pw=flowrate*m_Mu*m_xside/K+P;
1553
else if(m_outflow.X()==-1 || m_outflow.X()==2){
1554
Vw=K*(0-P)/m_xside/m_Mu/Phi;Pw=0;
1556
else {Vw=999999;Pw=999999;} //closed boundary
1558
Vw=0.5*(K+Kw)*(P-Pw)/m_xside/m_Mu/Phi;
1561
if(fabs(m_max_corner.X()-m_dim-m_pmax_global.X())<1e-6 && ix==(m_xcell-2)){ //cell located at east boundary
1562
if(m_inflow.X()==-1 || m_inflow.X()==2){
1563
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_xside;}
1564
else{flowrate=m_flowrate;};
1565
Ve=flowrate/Phi;Pe=flowrate*m_Mu*m_xside/K+P;
1567
else if(m_outflow.X()==1 || m_outflow.X()==2){
1568
Ve=K*(0-P)/m_xside/m_Mu/Phi;Pe=0;
1570
else {Ve=999999;Pe=999999;} //closed boundary
1572
Ve=0.5*(K+Ke)*(P-Pe)/m_xside/m_Mu/Phi;
1575
if(fabs(m_min_corner.Y()+m_dim-m_p0_global.Y())<1e-6 && iy==1){ //cell located at north boundary
1576
if(m_inflow.Y()==1 || m_inflow.Y()==2){
1577
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_yside;}
1578
else{flowrate=m_flowrate;};
1579
Vn=flowrate/Phi;Pn=flowrate*m_Mu*m_yside/K+P;
1581
else if(m_outflow.Y()==-1 || m_outflow.Y()==2){
1582
Vn=K*(0-P)/m_yside/m_Mu/Phi;Pn=0;
1584
else {Vn=999999;Pn=999999;} //closed boundary
1586
Vn=0.5*(K+Kn)*(P-Pn)/m_yside/m_Mu/Phi;
1589
if(fabs(m_max_corner.Y()-m_dim-m_pmax_global.Y())<1e-6 && iy==(m_ycell-2)){ //cell located at south boundary
1590
if(m_inflow.Y()==-1 || m_inflow.Y()==2){
1591
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_yside;}
1592
else{flowrate=m_flowrate;};
1593
Vs=flowrate/Phi;Ps=flowrate*m_Mu*m_yside/K+P;
1595
else if(m_outflow.Y()==1 || m_outflow.Y()==2){
1596
Vs=K*(0-P)/m_yside/m_Mu/Phi;Ps=0;
1598
else {Vs=999999;Ps=999999;} //closed boundary
1600
Vs=0.5*(K+Ks)*(P-Ps)/m_yside/m_Mu/Phi;
1603
if(fabs(m_min_corner.Z()+m_dim-m_p0_global.Z())<1e-6 && iz==1){ //cell located at lower boundary
1604
if(m_inflow.Z()==1 || m_inflow.Z()==2){
1605
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_zside;}
1606
else{flowrate=m_flowrate;};
1607
Vd=flowrate/Phi;Pd=flowrate*m_Mu*m_zside/K+P;
1609
else if(m_outflow.Z()==-1 || m_outflow.Z()==2){
1610
Vd=K*(0-P)/m_zside/m_Mu/Phi;Pd=0;
1612
else {Vd=999999;Pd=999999;} //closed boundary
1614
Vd=0.5*(K+Kd)*(P-Pd)/m_zside/m_Mu/Phi;
1617
if(fabs(m_max_corner.Z()-m_dim-m_pmax_global.Z())<1e-6 && iz==(m_zcell-2)){ //cell located at upper boundary
1618
if(m_inflow.Z()==-1 || m_inflow.Z()==2){
1619
if(m_flowrate==0){flowrate=K*m_pressure/m_Mu/m_zside;}
1620
else{flowrate=m_flowrate;};
1621
Vu=flowrate/Phi;Pu=flowrate*m_Mu*m_zside/K+P;
1623
else if(m_outflow.Z()==1 || m_outflow.Z()==2){
1624
Vu=K*(0-P)/m_zside/m_Mu/Phi;Pu=0;
1626
else {Vu=999999;Pu=999999;} //closed boundary
1628
Vu=0.5*(K+Ku)*(P-Pu)/m_zside/m_Mu/Phi;
1631
double Vx,Vy,Vz,Px,Py,Pz;
1632
if(Vw==999999 && Ve==999999){
1634
} else if(Vw==999999){
1635
Vx=Ve;Px=-Pe/m_xside;
1636
} else if(Ve==999999){
1637
Vx=-Vw;Px=Pw/m_xside;
1639
Vx=(-Vw+Ve)/2.0;Px=(Pw-Pe)/2.0/m_xside;
1642
if(Vn==999999 && Vs==999999){
1644
} else if(Vn==999999){
1645
Vy=Vs;Py=-Ps/m_yside;
1646
} else if(Vs==999999){
1647
Vy=-Vn;Py=Pn/m_yside;
1649
Vy=(-Vn+Vs)/2.0;Py=(Pn-Ps)/2.0/m_yside;
1652
if(Vd==999999 && Vu==999999){
1654
} else if(Vd==999999){
1655
Vz=Vu;Pz=-Pu/m_zside;
1656
} else if(Vu==999999){
1657
Vz=-Vd;Pz=Pd/m_zside;
1659
Vz=(-Vd+Vu)/2.0;Pz=(Pd-Pu)/2.0/m_zside;
1661
m_cells[idx].setVf(Vec3(Vx,Vy,Vz));//fluid velocity
1662
m_cells[idx].setPg(Vec3(Px,Py,Pz));//pressure gradient
1669
template<typename T>
1670
vector<CFluidCell> NeighborTable<T>::get_yz_cellslab(int x)
1672
vector<CFluidCell> res;
1673
for(int iy=1;iy<m_ycell-1;iy++){
1674
for(int iz=1;iz<m_zcell-1;iz++){
1675
int idx=cellindex(x,iy,iz);
1676
res.push_back(m_cells[idx]);
1683
template<typename T>
1684
vector<CFluidCell> NeighborTable<T>::get_xz_cellslab(int y)
1686
vector<CFluidCell> res;;
1687
for(int ix=1;ix<m_xcell-1;ix++){
1688
for(int iz=1;iz<m_zcell-1;iz++){
1689
int idx=cellindex(ix,y,iz);
1690
res.push_back(m_cells[idx]);
1697
template<typename T>
1698
vector<CFluidCell> NeighborTable<T>::get_xy_cellslab(int z)
1700
vector<CFluidCell> res;
1701
for(int ix=1;ix<m_xcell-1;ix++){
1702
for(int iy=1;iy<m_ycell-1;iy++){
1703
int idx=cellindex(ix,iy,z);
1704
res.push_back(m_cells[idx]);
1712
template<typename T>
1713
void NeighborTable<T>::set_yz_cellslab(int x, vector<CFluidCell> recv_slab)
1715
if(recv_slab.size()==(m_ycell-2)*(m_zcell-2)){
1717
for(int iy=1;iy<m_ycell-1;iy++){
1718
for(int iz=1;iz<m_zcell-1;iz++){
1719
int idx=cellindex(x,iy,iz);
1720
m_cells[idx]=recv_slab[number];
1725
//cerr << "FluidcellTable<T>::set_yz_slab ERROR: size mismatch in received data, recv_slab.size()!=m_ycell*m_zcell - (" << recv_slab.size() << "!=" << m_ycell*m_zcell << ")"<< std::endl;
1729
template<typename T>
1730
void NeighborTable<T>::set_xz_cellslab(int y, vector<CFluidCell> recv_slab)
1732
if(recv_slab.size()==(m_xcell-2)*(m_zcell-2)){
1734
for(int ix=1;ix<m_ycell-1;ix++){
1735
for(int iz=1;iz<m_zcell-1;iz++){
1736
int idx=cellindex(ix,y,iz);
1737
m_cells[idx]=recv_slab[number];
1742
//cerr << "FluidcellTable<T>::set_xz_slab ERROR: size mismatch in received data, recv_slab.size()!=m_xcell*m_zcell - (" << recv_slab.size() << "!=" << m_xcell*m_zcell << ")"<< std::endl;
1746
template<typename T>
1747
void NeighborTable<T>::set_xy_cellslab(int z, vector<CFluidCell> recv_slab)
1749
if(recv_slab.size()==(m_xcell-2)*(m_ycell-2)){
1751
for(int ix=1;ix<m_xcell-1;ix++){
1752
for(int iy=1;iy<m_ycell-1;iy++){
1753
int idx=cellindex(ix,iy,z);
1754
m_cells[idx]=recv_slab[number];
1759
//cerr << "FluidcellTable<T>::set_xy_slab ERROR: size mismatch in received data, recv_slab.size()!=m_xcell*m_ycell - (" << recv_slab.size() << "!=" << m_xcell*m_ycell << ")"<< std::endl;
1765
Get a value for each fluid cell using a fluid cell member function and return a vector
1766
of values, with position of cell.
1768
\param rdf the fluid cell member function
1770
template<typename T>
1771
template<typename P>
1772
vector<pair<Vec3,P> > NeighborTable<T>::forAllInnerCellsGet(P (CFluidCell::*rdf)() const)
1774
vector<pair<Vec3,P> > res;
1775
for(int ix=1;ix<m_xcell-1;ix++){
1776
for(int iy=1;iy<m_ycell-1;iy++){
1777
for(int iz=1;iz<m_zcell-1;iz++){
1778
int idx=cellindex(ix,iy,iz);
1779
Vec3 global_pos=m_cells[idx].getPos();
1780
res.push_back(make_pair(global_pos,(m_cells[idx].*rdf)()));
1789
Get a value for each fluid cell using a fluid cell member function and return a vector
1790
of values,with global index of cell
1792
\param rdf the fluid cell member function
1794
template<typename T>
1795
template<typename P>
1796
vector<pair<Vec3,P> > NeighborTable<T>::forAllInnerCellsGetIndexed(P (CFluidCell::*rdf)() const)
1798
vector<pair<Vec3,P> > res;
1799
for(int ix=1;ix<m_xcell-1;ix++){
1800
for(int iy=1;iy<m_ycell-1;iy++){
1801
for(int iz=1;iz<m_zcell-1;iz++){
1802
int idx=cellindex(ix,iy,iz);
1803
Vec3 global_index=m_cells[idx].getIndex();
1804
res.push_back(make_pair(global_index,(m_cells[idx].*rdf)()));
1812
template<typename T>
1813
template<typename P>
1814
vector<P> NeighborTable<T>::forAllInnerCellsGetSum(P (CFluidCell::*rdf)() const)
1817
for(int ix=1;ix<m_xcell-1;ix++){
1818
for(int iy=1;iy<m_ycell-1;iy++){
1819
for(int iz=1;iz<m_zcell-1;iz++){
1820
int idx=cellindex(ix,iy,iz);
1821
res.push_back((m_cells[idx].*rdf)());
1828
/****fluid contents: end****/