// ################################################################# // 無次元内部エネルギーから有次元/無次元温度への変換 void FBUtility::convArrayIE2Tmp(REAL_TYPE* dst, const int* size, const int guide, const REAL_TYPE* src, const int* bd, const double* mtbl, const REAL_TYPE Base_tmp, const REAL_TYPE Diff_tmp, const int mode, double& flop) { int ix = size[0]; int jx = size[1]; int kx = size[2]; int gd = guide; int zz = mode; // dst[]の次元 1=dimensional, 0=non-dimensional REAL_TYPE dp = fabs(Diff_tmp); REAL_TYPE bt = Base_tmp; flop += (double)ix * (double)jx * (double)kx * 11.0 + 1.0; #pragma omp parallel for firstprivate(ix, jx, kx, gd, dp, bt, zz) schedule(static) collapse(2) for (int k=1-gd; k<=kx+gd; k++) { for (int j=1-gd; j<=jx+gd; j++) { for (int i=1-gd; i<=ix+gd; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); int l = bd[m] & MASK_5; REAL_TYPE rho = mtbl[3*l+0]; REAL_TYPE cp = mtbl[3*l+1]; REAL_TYPE tn = src[m] / (rho * cp); dst[m] = (zz==1) ? (tn * dp + bt) : tn; } } } }
// ################################################################# // S3D配列のコピー void FBUtility::copyS3D(REAL_TYPE* dst, const int* size, const int guide, const REAL_TYPE* src, const REAL_TYPE scale) { REAL_TYPE s = scale; int ix = size[0]; int jx = size[1]; int kx = size[2]; int gd = guide; #pragma omp parallel for firstprivate(ix, jx, kx, gd, s) schedule(static) collapse(2) for (int k=1-gd; k<=kx+gd; k++) { for (int j=1-gd; j<=jx+gd; j++) { for (int i=1-gd; i<=ix+gd; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); dst[m] = s * src[m]; } } } }
/** * @brief S3D配列の初期化 (Int) * @param [out] dst 出力 * @param [in] size 配列サイズ * @param [in] guide ガイドセルサイズ * @param [in] init 定数 */ void FBUtility::initS3D(int* dst, const int* size, const int guide, const int init) { int s = init; int ix = size[0]; int jx = size[1]; int kx = size[2]; int gd = guide; #pragma omp parallel for firstprivate(ix, jx, kx, gd, s) schedule(static) collapse(2) for (int k=1-gd; k<=kx+gd; k++) { for (int j=1-gd; j<=jx+gd; j++) { for (int i=1-gd; i<=ix+gd; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); dst[m] = s; } } } }
// ################################################################# // 全圧データについて,無次元から有次元単位に変換する void FBUtility::convArrayTpND2D(REAL_TYPE* src, const int* size, const int guide, const REAL_TYPE Ref_rho, const REAL_TYPE Ref_v) { REAL_TYPE cf = Ref_rho * Ref_v * Ref_v; int ix = size[0]; int jx = size[1]; int kx = size[2]; int gd = guide; #pragma omp parallel for firstprivate(ix, jx, kx, gd, cf) schedule(static) collapse(2) for (int k=1-gd; k<=kx+gd; k++) { for (int j=1-gd; j<=jx+gd; j++) { for (int i=1-gd; i<=ix+gd; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); src[m] *= cf; } } } }
// ################################################################# // 圧力値を有次元から無次元へ変換 void FBUtility::convArrayPrsD2ND(REAL_TYPE* dst, const int* size, const int guide, const REAL_TYPE Base_prs, const REAL_TYPE Ref_rho, const REAL_TYPE Ref_v, double& flop) { int ix = size[0]; int jx = size[1]; int kx = size[2]; int gd = guide; REAL_TYPE dp = 1.0 / (Ref_rho * Ref_v * Ref_v); REAL_TYPE bp = Base_prs; flop += (double)ix * (double)jx * (double)kx * 2.0 + 10.0; #pragma omp parallel for firstprivate(ix, jx, kx, gd, dp, bp) schedule(static) collapse(2) for (int k=1-gd; k<=kx+gd; k++) { for (int j=1-gd; j<=jx+gd; j++) { for (int i=1-gd; i<=ix+gd; i++) { size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); dst[m] = ( dst[m] - bp ) * dp; } } } }
// ################################################################# // svxフォーマットで出力する(IDのみ) bool ActiveSubdomain::writeSVX(const string& path, const REAL_TYPE* pch, const REAL_TYPE* org) { ofstream ofs(path.c_str(), ios::out | ios::binary); if (!ofs) { cout << "\tCan't open " << path.c_str() << " file" << endl; return false; } float dx = pch[0]; float dy = pch[1]; float dz = pch[2]; float ox = org[0]; float oy = org[1]; float oz = org[2]; int *q = new int[x*y*z]; for (int k=1; k<=z; k++) { for (int j=1; j<=y; j++) { for (int i=1; i<=x; i++) { size_t m = _F_IDX_S3D(i, j, k, x, y, z, 0); q[m] = (int)contents[m]; } } } int sz; // voxel size sz = sizeof(int)*3; ofs.write( (char*)&sz, sizeof(int) ); ofs.write( (char*)&x, sizeof(int) ); ofs.write( (char*)&y, sizeof(int) ); ofs.write( (char*)&z, 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 = x*y*z * 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; }
// ################################################################# // 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; } } }
// ################################################################# // sphファイルの書き出し(内部領域のみ) void FileIO::writeRawSPH(const REAL_TYPE *vf, const int* sz, const int gc, const REAL_TYPE* org, const REAL_TYPE* ddx, const int m_ModePrecision) { int pad, dType, stp, svType; int i, j, k; REAL_TYPE ox, oy, oz, dx, dy, dz, tm; long long szl[3], stpl; char sph_fname[512]; if ( paraMngr->IsParallel() ) { sprintf( sph_fname, "field%010d.sph", paraMngr->GetMyRankID() ); } else { sprintf( sph_fname, "field.sph" ); } ofstream ofs(sph_fname, ios::out | ios::binary); if (!ofs) { cout << "\tCan't open " << sph_fname << " file" << endl; Exit(0); } int ix = sz[0]; //+2*gc; int jx = sz[1]; //+2*gc; int kx = sz[2]; //+2*gc; int gd = gc; size_t nx = ix * jx * kx; ox = org[0]; //-ddx[0]*(REAL_TYPE)gc; oy = org[1]; //-ddx[1]*(REAL_TYPE)gc; oz = org[2]; //-ddx[2]*(REAL_TYPE)gc; dx = ddx[0]; dy = ddx[1]; dz = ddx[2]; //printf("org: %f %f %f\n", ox, oy, oz); //printf("dx : %f %f %f\n", dx, dy, dz); svType = kind_scalar; if ( sizeof(REAL_TYPE) == sizeof(double) ) { for (i=0; i<3; i++) szl[i] = (long long)sz[i]; } REAL_TYPE *f = new REAL_TYPE[nx]; size_t m, l; for (k=1; k<=kx; k++) { for (j=1; j<=jx; j++) { for (i=1; i<=ix; i++) { l = _F_IDX_S3D(i, j, k, ix, jx, kx, 0); m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd); f[l] = (REAL_TYPE)vf[m]; } } } // data property ( m_ModePrecision == sizeof(float) ) ? dType=1 : dType=2; 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 if (dType == 1) { 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) ); } else { pad = sizeof(long long)*3; ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&szl[0], sizeof(long long) ); ofs.write( (char*)&szl[1], sizeof(long long) ); ofs.write( (char*)&szl[2], sizeof(long long) ); ofs.write( (char*)&pad, sizeof(int) ); } // original point of domain if (dType == 1) { 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) ); } else { pad = sizeof(double)*3; ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&ox, sizeof(double) ); ofs.write( (char*)&oy, sizeof(double) ); ofs.write( (char*)&oz, sizeof(double) ); ofs.write( (char*)&pad, sizeof(int) ); } // pitch of voxel if (dType == 1) { pad = sizeof(float)*3; 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) ); } else { pad = sizeof(double)*3; ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&dx, sizeof(double) ); ofs.write( (char*)&dy, sizeof(double) ); ofs.write( (char*)&dz, sizeof(double) ); ofs.write( (char*)&pad, sizeof(int) ); } // time stamp if (dType == 1) { stp = 0; 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) ); } else { stpl =0; tm = 0.0; pad = sizeof(long long)+sizeof(double); ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)&stpl, sizeof(long long) ); ofs.write( (char*)&tm, sizeof(double) ); ofs.write( (char*)&pad, sizeof(int) ); } if (svType == kind_scalar) { pad = (m_ModePrecision == sizeof(float)) ? nx * sizeof(float) : nx * sizeof(double); ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)f, pad ); ofs.write( (char*)&pad, sizeof(int) ); } ofs.close(); if (f) { delete [] f; f=NULL; } }
// ################################################################# // BCflagをbvxで出力する int IO_BASE::writeBCflag(const int out_gc) { if (IO_BCflag != ON) 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 int unsigned* buf = new unsigned[nx]; // start index Active, State bitはマスクする >> 30bitのみ unsigned val = (unsigned)(d_cdf[ _F_IDX_S3D(1-gc, 1-gc, 1-gc, ix, jx, kx, gd) ] & 0x3fffffff); 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); unsigned tmp = (unsigned)(d_cdf[m0] & 0x3fffffff); buf[m1] = tmp; if ( tmp == val ) c++; } } } bool ret = false; int ret_val=0; // サブドメイン内が同じ値の時(c==nx)には、BCflag配列を書き出さない if ( c != nx ) { ret = BVX_IO::Save_Block_BCflag(size, gc, bitWidth, rank, OutDirPath, buf, BVXcomp); if ( !ret ) { stamped_printf("\tError : when saving BCflag\n"); Exit(0); } ret_val = -1; } else { ret_val = (int)val; } if (buf) { delete [] buf; buf = NULL; } return ret_val; }
// ################################################################# // 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; }
// ################################################################# // 例題のモデルを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; }
// ################################################################# // sphファイルの書き出し(内部領域のみ) void IO_BASE::writeRawSPH(const int *array) { int pad, dType, stp, svType; float ox, oy, oz, dx, dy, dz, tm; long long szl[3], stpl; char sph_fname[512]; if ( paraMngr->IsParallel() ) { sprintf( sph_fname, "field%010d.sph", paraMngr->GetMyRankID(procGrp) ); } else { sprintf( sph_fname, "field.sph" ); } ofstream ofs(sph_fname, ios::out | ios::binary); if (!ofs) { printf("\tCan't open %s file\n", sph_fname); Exit(0); } // 出力ガイドセル数 int gc_out = 1; int imax = size[0]; int jmax = size[1]; int kmax = size[2]; int ix = size[0]+gc_out*2; int jx = size[1]+gc_out*2; int kx = size[2]+gc_out*2; int gd = guide; size_t nx = 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*gc_out; // シフト oy = (float)origin[1]*C->RefLength - dy*gc_out; oz = (float)origin[2]*C->RefLength - dz*gc_out; //printf("org: %f %f %f\n", ox, oy, oz); //printf("dx : %f %f %f\n", dx, dy, dz); svType = kind_scalar; float *f = new float[nx]; size_t m, l; #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); f[l] = array[m]; } } } // data property dType=1; 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 pad = sizeof(float)*3; 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 stp = 0; 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) ); pad = nx * sizeof(float); ofs.write( (char*)&pad, sizeof(int) ); ofs.write( (char*)f, pad ); ofs.write( (char*)&pad, sizeof(int) ); ofs.close(); if (f) { delete [] f; f=NULL; } }
// ################################################################# // モデル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) 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; } }
// ################################################################# // 計算領域のセルIDとカット情報を設定する void IP_Step::setup(int* bcd, Control* R, const int NoMedium, const MediumList* mat, const int NoCompo, const CompoList* cmp, long long* cut, int* bid) { int mid_fluid; /// 流体 int mid_solid; /// 固体 // 流体 if ( (mid_fluid = FBUtility::findIDfromLabel(mat, NoMedium, m_fluid)) == 0 ) { Hostonly_ printf("\tLabel '%s' is not listed in MediumList\n", m_fluid.c_str()); Exit(0); } // 固体 if ( (mid_solid = FBUtility::findIDfromLabel(mat, NoMedium, m_solid)) == 0 ) { Hostonly_ printf("\tLabel '%s' is not listed in MediumList\n", m_solid.c_str()); Exit(0); } // ローカル int ix = size[0]; int jx = size[1]; int kx = size[2]; int gd = guide; REAL_TYPE dx = pitch[0]; //REAL_TYPE dy = pitch[1]; REAL_TYPE dz = pitch[2]; // ローカルな無次元位置 REAL_TYPE ox, oz; ox = origin[0]; oz = origin[2]; // step length 有次元値 REAL_TYPE len = G_origin[0] + width/R->RefLength; // グローバルな無次元位置 // step height 有次元値 REAL_TYPE ht = G_origin[2] + height/R->RefLength; // グローバルな無次元位置 #pragma omp parallel for firstprivate(ix, jx, kx, gd, mid_solid, ox, oz, dx, dz, len, ht) 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); REAL_TYPE x = ox + 0.5*dx + dx*(i-1); // position of cell center REAL_TYPE z = oz + 0.5*dz + dz*(k-1); // position of cell center REAL_TYPE s = (len - x)/dx; if ( z <= ht ) { if ( (x <= len) && (len < x+dx) ) { setBit5(bid[m], mid_solid, X_plus); int r = quantize9(s); setCut9(cut[m], r, X_plus); size_t m1 = _F_IDX_S3D(i+1, j, k, ix, jx, kx, gd); setBit5(bid[m1], mid_solid, X_minus); int rr = quantize9(1.0-s); setCut9(cut[m1], rr, X_minus); } else if ( (x-dx < len) && (len < x) ) { setBit5(bid[m], mid_solid, X_minus); int r = quantize9(-s); setCut9(cut[m], r, X_minus); size_t m1 = _F_IDX_S3D(i-1, j, k, ix, jx, kx, gd); setBit5(bid[m1], mid_solid, X_plus); int rr = quantize9(1.0+s); setCut9(cut[m1], rr, X_plus); } } } } } #pragma omp parallel for firstprivate(ix, jx, kx, gd, mid_solid, ox, oz, dx, dz, len, ht) 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); REAL_TYPE x = ox + 0.5*dx + dx*(i-1); // position of cell center REAL_TYPE z = oz + 0.5*dz + dz*(k-1); // position of cell center REAL_TYPE c = (ht - z)/dz; if ( x <= len ) { if ( (z <= ht) && (ht < z+dz) ) { setBit5(bid[m], mid_solid, Z_plus); int r = quantize9(c); setCut9(cut[m], r, Z_plus); size_t m1 = _F_IDX_S3D(i, j, k+1, ix, jx, kx, gd); setBit5(bid[m1], mid_solid, Z_minus); int rr = quantize9(1.0-c); setCut9(cut[m1], rr, Z_minus); } else if ( (z-dz < ht) && (ht < z) ) { setBit5(bid[m], mid_solid, Z_minus); int r = quantize9(-c); setCut9(cut[m], r, Z_minus); size_t m1 = _F_IDX_S3D(i, j, k-1, ix, jx, kx, gd); setBit5(bid[m1], mid_solid, Z_plus); int rr = quantize9(1.0+c); setCut9(cut[m1], rr, Z_plus); } } } } } // ステップ部のガイドセルの設定 // 隣接ランクのIDを取得 nID[6] const int* nID = paraMngr->GetNeighborRankID(procGrp); if ( nID[X_minus] < 0 ) { // デフォルトでガイドセルをSolidにする #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++) { // 媒質エントリ size_t m = _F_IDX_S3D(0, j, k, ix, jx, kx, gd); setMediumID(bcd[m], mid_solid); // 交点 size_t l = _F_IDX_S3D(1 , j , k , ix, jx, kx, gd); int r = quantize9(0.5); setCut9(cut[l], r, X_minus); // 境界ID setBit5(bid[l], mid_solid, X_minus); } } // Channel #pragma omp parallel for firstprivate(ix, jx, kx, gd, mid_fluid, ht, oz, dz) schedule(static) for (int k=1; k<=kx; k++) { for (int j=1; j<=jx; j++) { REAL_TYPE z = oz + ( (REAL_TYPE)k-0.5 ) * dz; if ( z > ht ) { size_t m = _F_IDX_S3D(0, j, k, ix, jx, kx, gd); setMediumID(bcd[m], mid_fluid); size_t l = _F_IDX_S3D(1 , j , k , ix, jx, kx, gd); int r = quantize9(1.0); setCut9(cut[l], r, X_minus); setBit5(bid[l], 0, X_minus); } } } } }