// ################################################################# // Ductの計算領域のセルIDを設定する void IP_Duct::setup(int* bcd, Control* R, REAL_TYPE* G_org, const int NoMedium, const MediumList* mat, float* cut, int* bid) { int mid_fluid=1; /// 流体 int mid_solid=2; /// 固体 int mid_driver=3; /// ドライバ部 int mid_driver_face=4; /// ドライバ流出面 REAL_TYPE x, y, z, dh, r, len; REAL_TYPE ox, oy, oz, Lx, Ly, Lz; // ローカルにコピー int ix = size[0]; int jx = size[1]; int kx = size[2]; int gd = guide; // 隣接ランクのIDを取得 nID[6] const int* nID = paraMngr->GetNeighborRankID(); ox = origin[0]; oy = origin[1]; oz = origin[2]; Lx = region[0]; Ly = region[1]; Lz = region[2]; dh = deltaX; r = driver.diameter/R->RefLength * 0.5; len= driver.length/R->RefLength; // Initialize #pragma omp parallel for firstprivate(ix, jx, kx, gd, mid_solid) schedule(static) for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); bcd[m] = 0; } } } // Inner if (driver.shape == id_rectangular ) { // 矩形管の場合は内部は全て流体 #pragma omp parallel for firstprivate(ix, jx, kx, gd, mid_fluid) \ schedule(static) for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); bcd[m] = 0; } } } } else { // 円管の場合,半径以下のセルを流体にする(ノードにかかわらず) switch (driver.direction) { case X_minus: case X_plus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); y = oy + 0.5*dh + dh*(j-1); z = oz + 0.5*dh + dh*(k-1); if ( (y-r)*(y-r)+(z-r)*(z-r) <= r*r ) bcd[m] |= mid_fluid; } } } break; case Y_minus: case Y_plus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); x = ox + 0.5*dh + dh*(i-1); z = oz + 0.5*dh + dh*(k-1); if ( (x-r)*(x-r)+(z-r)*(z-r) <= r*r ) bcd[m] |= mid_fluid; } } } break; case Z_minus: case Z_plus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); x = ox + 0.5*dh + dh*(i-1); y = oy + 0.5*dh + dh*(j-1); if ( (x-r)*(x-r)+(y-r)*(y-r) <= r*r ) bcd[m] |= mid_fluid; } } } break; } } // ドライバ部分 if ( driver.length > 0.0 ) { switch (driver.direction) { case X_minus: if ( nID[driver.direction] < 0 ) { for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); x = ox + 0.5*dh + dh*(i-1); y = oy + 0.5*dh + dh*(j-1); z = oz + 0.5*dh + dh*(k-1); if ( x < ox+len ) { if ( driver.shape == id_circular ) { if ( (y-r)*(y-r)+(z-r)*(z-r) <= r*r ) bcd[m] |= mid_driver; // 半径以内をドライバIDにする } else { bcd[m] |= mid_driver; } } } } } } break; case X_plus: if ( nID[driver.direction] < 0 ) { for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); x = ox + 0.5*dh + dh*(i-1); y = oy + 0.5*dh + dh*(j-1); z = oz + 0.5*dh + dh*(k-1); if ( x > ox+Lx-len ) { if ( driver.shape == id_circular ) { if ( (y-r)*(y-r)+(z-r)*(z-r) <= r*r ) bcd[m] |= mid_driver; } else { bcd[m] |= mid_driver; } } } } } } break; case Y_minus: if ( nID[driver.direction] < 0 ) { for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); x = ox + 0.5*dh + dh*(i-1); y = oy + 0.5*dh + dh*(j-1); z = oz + 0.5*dh + dh*(k-1); if ( y < oy+len ) { if ( driver.shape == id_circular ) { if ( (x-r)*(x-r)+(z-r)*(z-r) <= r*r ) bcd[m] |= mid_driver; } else { bcd[m] |= mid_driver; } } } } } } break; case Y_plus: if ( nID[driver.direction] < 0 ) { for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); x = ox + 0.5*dh + dh*(i-1); y = oy + 0.5*dh + dh*(j-1); z = oz + 0.5*dh + dh*(k-1); if ( y > oy+Ly-len ) { if ( driver.shape == id_circular ) { if ( (x-r)*(x-r)+(z-r)*(z-r) <= r*r ) bcd[m] |= mid_driver; } else { bcd[m] |= mid_driver; } } } } } } break; case Z_minus: if ( nID[driver.direction] < 0 ) { for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); x = ox + 0.5*dh + dh*(i-1); y = oy + 0.5*dh + dh*(j-1); z = oz + 0.5*dh + dh*(k-1); if ( z < oz+len ) { if ( driver.shape == id_circular ) { if ( (x-r)*(x-r)+(y-r)*(y-r) <= r*r ) bcd[m] |= mid_driver; } else { bcd[m] |= mid_driver; } } } } } } break; case Z_plus: if ( nID[driver.direction] < 0 ) { for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); x = ox + 0.5*dh + dh*(i-1); y = oy + 0.5*dh + dh*(j-1); z = oz + 0.5*dh + dh*(k-1); if ( z > oz+Lz-len ) { if ( driver.shape == id_circular ) { if ( (x-r)*(x-r)+(y-r)*(y-r) <= r*r ) bcd[m] |= mid_driver; } else { bcd[m] |= mid_driver; } } } } } } break; } } // ドライバの下流面にIDを設定 if ( driver.length > 0.0 ) { switch (driver.direction) { case X_minus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); size_t m1= _F_IDX_S3D(i+1, j, k, ix, jx, kx, gd); if ( (DECODE_CMP( bcd[m] ) == mid_driver) && (DECODE_CMP( bcd[m1] ) == mid_fluid) ) { bcd[m] |= mid_driver_face; } } } } break; case X_plus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); size_t m1= _F_IDX_S3D(i-1, j, k, ix, jx, kx, gd); if ( (DECODE_CMP( bcd[m] ) == mid_driver) && (DECODE_CMP( bcd[m1] ) == mid_fluid) ) { bcd[m] |= mid_driver_face; } } } } break; case Y_minus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); size_t m1= _F_IDX_S3D(i, j+1, k, ix, jx, kx, gd); if ( (DECODE_CMP( bcd[m] ) == mid_driver) && (DECODE_CMP( bcd[m1] ) == mid_fluid) ) { bcd[m] |= mid_driver_face; } } } } break; case Y_plus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); size_t m1= _F_IDX_S3D(i, j-1, k, ix, jx, kx, gd); if ( (DECODE_CMP( bcd[m] ) == mid_driver) && (DECODE_CMP( bcd[m1] ) == mid_fluid) ) { bcd[m] |= mid_driver_face; } } } } break; case Z_minus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); size_t m1= _F_IDX_S3D(i, j, k+1, ix, jx, kx, gd); if ( (DECODE_CMP( bcd[m] ) == mid_driver) && (DECODE_CMP( bcd[m1] ) == mid_fluid) ) { bcd[m] |= mid_driver_face; } } } } break; case Z_plus: for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { for (int i=1; i<=ix; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); size_t m1= _F_IDX_S3D(i, j, k-1, ix, jx, kx, gd); if ( (DECODE_CMP( bcd[m] ) == mid_driver) && (DECODE_CMP( bcd[m1] ) == mid_fluid) ) { bcd[m] |= mid_driver_face; } } } } break; } } }
// ################################################################# // Cell IDをbvxで出力する int IO_BASE::writeCellID(const int out_gc) { if (IO_Voxel != voxel_BVX) return 0; unsigned bitWidth = 5; int rank = paraMngr->GetMyRankID(procGrp); int ix = size[0]; int jx = size[1]; int kx = size[2]; int gc = out_gc; int gd = guide; size_t nx = (ix+2*gc) * (jx+2*gc) * (kx+2*gc); // unsignd char u8 *buf = new u8[nx]; // start indexの値 下位5bitの値のみ u8 val = DECODE_CMP(d_bcd[ _F_IDX_S3D(1-gc, 1-gc, 1-gc, ix, jx, kx, gd) ]); int c=0; #pragma omp parallel for firstprivate(ix, jx, kx, gc, gd, val) schedule(static) reduction(+:c) for (int k=1-gc; k<=kx+gc; k++) { for (int j=1-gc; j<=jx+gc; j++) { for (int i=1-gc; i<=ix+gc; i++) { size_t m0 = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); size_t m1 = _F_IDX_S3D(i, j, k, ix, jx, kx, gc); u8 tmp = DECODE_CMP(d_bcd[m0]); buf[m1] = tmp; if ( tmp == val ) c++; } } } bool ret = false; int ret_val=0; // サブドメイン内が全て同じ値の時(c==nx)には、CellID配列を書き出さずに戻り値はval if ( c != nx ) { ret = BVX_IO::Save_Block_CellID(size, gc, bitWidth, rank, OutDirPath, buf, BVXcomp); if ( !ret ) { stamped_printf("\tError : when saving CellID\n"); Exit(0); } ret_val = -1; } else { ret_val = (int)val; } if (buf) { delete [] buf; buf = NULL; } return ret_val; }
// ################################################################# // モデルIDをsphフォーマット(float)で出力する void Intrinsic::writeSPH(const int *bcd, const Control* R) { int ix, jx, kx; float ox, oy, oz, dx, dy, dz; char fname[64]; if ( paraMngr->IsParallel() ) { sprintf( fname, "model_%06d.sph", paraMngr->GetMyRankID(procGrp) ); } else { sprintf( fname, "model.sph" ); } ofstream ofs(fname, ios::out | ios::binary); if (!ofs) { cout << "\tCan't open " << fname << " file" << endl; Exit(0); } int imax = size[0]; int jmax = size[1]; int kmax = size[2]; int gd = guide; ix = imax+2; // +2 means guide cell jx = jmax+2; kx = kmax+2; size_t nx = (size_t)(ix*jx*kx); dx = (float)pitch[0]*RefL; dy = (float)pitch[1]*RefL; dz = (float)pitch[2]*RefL; ox = (float)origin[0]*RefL - dx; // 片側1層分をシフト oy = (float)origin[1]*RefL - dy; oz = (float)origin[2]*RefL - dz; float *q = new float[nx]; #pragma omp parallel for firstprivate(imax, jmax, kmax, ix, jx, gd) schedule(static) for (int k=0; k<=(kmax+1); k++) { for (int j=0; j<=(jmax+1); j++) { for (int i=0; i<=(imax+1); i++) { size_t l = (size_t)(ix*jx*k + ix*j + i); size_t m = _F_IDX_S3D(i, j, k, imax, jmax, kmax, gd); q[l] = (float)DECODE_CMP(bcd[m]); } } } // data property int dType = 1; // float int svType = 1; // scalar int pad = sizeof(int)*2; ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&svType, sizeof(int) ); ofs.write( (char*)&dType, sizeof(int) ); ofs.write( (char*)&pad, sizeof(int) ); // voxel size pad = sizeof(int)*3; ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&ix, sizeof(int) ); ofs.write( (char*)&jx, sizeof(int) ); ofs.write( (char*)&kx, sizeof(int) ); ofs.write( (char*)&pad, sizeof(int) ); // original point of domain pad = sizeof(float)*3; ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&ox, sizeof(float) ); ofs.write( (char*)&oy, sizeof(float) ); ofs.write( (char*)&oz, sizeof(float) ); ofs.write( (char*)&pad, sizeof(int) ); // pitch of voxel ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&dx, sizeof(float) ); ofs.write( (char*)&dy, sizeof(float) ); ofs.write( (char*)&dz, sizeof(float) ); ofs.write( (char*)&pad, sizeof(int) ); // time stamp int stp = 0; float tm = 0.0; pad = sizeof(int)+sizeof(float); ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&stp, sizeof(int) ); ofs.write( (char*)&tm, sizeof(float) ); ofs.write( (char*)&pad, sizeof(int) ); // medium ID pad = nx * sizeof(float); ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)q, pad ); ofs.write( (char*)&pad, sizeof(int) ); ofs.close(); if (q) { delete [] q; q=NULL; } }
// ################################################################# // 例題のモデルをsvxフォーマットで出力する(ID) bool IO_BASE::writeSVX(const int* array, const bool flag) { //if ( IO_Voxel != voxel_SVX ) return false; int sz, ix, jx, kx; size_t m, l; float ox, oy, oz, dx, dy, dz; char svx_fname[512]; if ( paraMngr->IsParallel() ) { sprintf( svx_fname, "example_%06d.svx", paraMngr->GetMyRankID(procGrp) ); } else { sprintf( svx_fname, "example.svx" ); } ofstream ofs(svx_fname, ios::out | ios::binary); if (!ofs) { cout << "\tCan't open " << svx_fname << " file" << endl; Exit(0); } int imax = size[0]; int jmax = size[1]; int kmax = size[2]; int gd = guide; ix = imax+2; // +2 means guide cell for IP model jx = jmax+2; kx = kmax+2; size_t nx = (size_t)(ix*jx*kx); dx = (float)pitch[0]*C->RefLength; dy = (float)pitch[1]*C->RefLength; dz = (float)pitch[2]*C->RefLength; ox = (float)origin[0]*C->RefLength - dx; // 片側1層分をシフト oy = (float)origin[1]*C->RefLength - dy; oz = (float)origin[2]*C->RefLength - dz; //stamped_printf("example out org(%e %e %e) dimensional\n", ox, oy, oz); int *q = new int[nx]; if ( !flag ) // d_bcd { #pragma omp parallel for firstprivate(imax, jmax, kmax, gd, ix, jx) schedule(static) for (int k=0; k<=(kmax+1); k++) { for (int j=0; j<=(jmax+1); j++) { for (int i=0; i<=(imax+1); i++) { size_t l = (size_t)(ix*jx*k + ix*j + i); size_t m = _F_IDX_S3D(i, j, k, imax, jmax, kmax, gd); q[l] = DECODE_CMP(array[m]); } } } } else // d_mid { #pragma omp parallel for firstprivate(imax, jmax, kmax, gd, ix, jx) schedule(static) for (int k=0; k<=(kmax+1); k++) { for (int j=0; j<=(jmax+1); j++) { for (int i=0; i<=(imax+1); i++) { size_t l = (size_t)(ix*jx*k + ix*j + i); size_t m = _F_IDX_S3D(i, j, k, imax, jmax, kmax, gd); q[l] = array[m]; } } } } // voxel size sz = sizeof(int)*3; ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&ix, sizeof(int) ); ofs.write( (char*)&jx, sizeof(int) ); ofs.write( (char*)&kx, sizeof(int) ); ofs.write( (char*)&sz, sizeof(int) ); // original point of domain sz = sizeof(float)*3; ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&ox, sizeof(float) ); ofs.write( (char*)&oy, sizeof(float) ); ofs.write( (char*)&oz, sizeof(float) ); ofs.write( (char*)&sz, sizeof(int) ); // pitch of voxel ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&dx, sizeof(float) ); ofs.write( (char*)&dy, sizeof(float) ); ofs.write( (char*)&dz, sizeof(float) ); ofs.write( (char*)&sz, sizeof(int) ); // type of stored data sz = sizeof(int)*1; int dtype = 0; dtype |= ( 0x1<<2 ); // medium ID ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&dtype, sizeof(int) ); ofs.write( (char*)&sz, sizeof(int) ); // medium ID sz = nx * sizeof(int); ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)q, sz ); ofs.write( (char*)&sz, sizeof(int) ); ofs.close(); if (q) { delete [] q; q=NULL; } return true; }
// ################################################################# // 例題のモデルをsvxフォーマットで出力する(ID) void Intrinsic::writeSVX(const int* bcd, Control* R) { int sz, ix, jx, kx; size_t m, l; float ox, oy, oz, dx, dy, dz; char svx_fname[512]; if ( paraMngr->IsParallel() ) { sprintf( svx_fname, "example_%06d.svx", paraMngr->GetMyRankID(procGrp) ); } else { sprintf( svx_fname, "example.svx" ); } ofstream ofs(svx_fname, ios::out | ios::binary); if (!ofs) { cout << "\tCan't open " << svx_fname << " file" << endl; Exit(0); } int imax = size[0]; int jmax = size[1]; int kmax = size[2]; int gd = guide; ix = imax+2; // +2 means guide cell for IP model jx = jmax+2; kx = kmax+2; size_t nx = (size_t)(ix*jx*kx); dx = (float)pitch[0]*RefL; dy = (float)pitch[1]*RefL; dz = (float)pitch[2]*RefL; ox = (float)origin[0]*RefL - dx; // 片側1層分をシフト oy = (float)origin[1]*RefL - dy; oz = (float)origin[2]*RefL - dz; //stamped_printf("example out org(%e %e %e) dimensional\n", ox, oy, oz); int *q = new int[nx]; for (int k=0; k<=(kmax+1); k++) { for (int j=0; j<=(jmax+1); j++) { for (int i=0; i<=(imax+1); i++) { l = (size_t)(ix*jx*k + ix*j + i); m = _F_IDX_S3D(i, j, k, imax, jmax, kmax, gd); q[l] = DECODE_CMP(bcd[m]); } } } // voxel size sz = sizeof(int)*3; ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&ix, sizeof(int) ); ofs.write( (char*)&jx, sizeof(int) ); ofs.write( (char*)&kx, sizeof(int) ); ofs.write( (char*)&sz, sizeof(int) ); // original point of domain sz = sizeof(float)*3; ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&ox, sizeof(float) ); ofs.write( (char*)&oy, sizeof(float) ); ofs.write( (char*)&oz, sizeof(float) ); ofs.write( (char*)&sz, sizeof(int) ); // pitch of voxel ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&dx, sizeof(float) ); ofs.write( (char*)&dy, sizeof(float) ); ofs.write( (char*)&dz, sizeof(float) ); ofs.write( (char*)&sz, sizeof(int) ); // type of stored data sz = sizeof(int)*1; int dtype = 0; dtype |= ( 0x1<<2 ); // medium ID ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&dtype, sizeof(int) ); ofs.write( (char*)&sz, sizeof(int) ); // medium ID sz = nx * sizeof(int); ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)q, sz ); ofs.write( (char*)&sz, sizeof(int) ); ofs.close(); if (q) { delete [] q; q=NULL; } }