示例#1
0
/**
 * @brief 円柱を設定
 * @param [in]     R        Controlクラスのポインタ
 * @param [in]     pos_x     中心座標(x,y) (無次元)
 * @param [in]     pos_y     中心座標(x,y) (無次元)
 * @param [in]     radius    半径 (無次元)
 * @param [in]     len_z     円柱のZ方向の長さ (無次元)
 * @param [in]     mid_solid 固体媒質ID
 * @param [out]    cut       カット情報
 * @param [out]    bid       境界ID
 */
void IP_Cylinder::setCircle(Control* R,
                            const REAL_TYPE pos_x,
                            const REAL_TYPE pos_y,
                            const REAL_TYPE radius,
                            const REAL_TYPE len_z,
                            const int mid_solid,
                            long long* cut,
                            int* bid)
{
  Vec3r pch(pitch);      ///< 無次元格子幅
  Vec3r org(origin);     ///< ノードローカル基点座標の無次元値

  
  REAL_TYPE dx = pitch[0];
  REAL_TYPE dy = pitch[1];
  REAL_TYPE dz = pitch[2];
  
  REAL_TYPE cx = pos_x;  ///< 円柱の中心座標(無次元)
  REAL_TYPE cy = pos_y;  ///< 円柱の中心座標(無次元)
  REAL_TYPE rs = radius; ///< 円柱の半径(無次元)
  
  int mid_s = mid_solid;
  
  // 球のbbox
  Vec3r box_min;  ///< Bounding boxの最小値
  Vec3r box_max;  ///< Bounding boxの最大値
  Vec3i box_st;   ///< Bounding boxの始点インデクス
  Vec3i box_ed;   ///< Bounding boxの終点インデクス
  box_min.assign( -(REAL_TYPE)rs+cx, -(REAL_TYPE)rs+cy, 0.0 ); // Z方向はダミー
  box_max.assign(  (REAL_TYPE)rs+cx,  (REAL_TYPE)rs+cy, 0.0 );
  box_st = find_index(box_min, org, pch);
  box_ed = find_index(box_max, org, pch);
  
  int ix = size[0];
  int jx = size[1];
  int kx = size[2];
  int gd = guide;
  
  
  // ローカルな無次元基点座標
  REAL_TYPE ox = origin[0];
  REAL_TYPE oy = origin[1];
  REAL_TYPE oz = origin[2];
  
  // グローバルな無次元座標
  REAL_TYPE zs = oz;
  REAL_TYPE ze;
  
  if ( mode == dim_2d )
  {
    ze = oz + region[2] + dz; // Z方向には全セルを対象, dzは安全係数
  }
  else
  {
    ze = oz + len_z; // Z-面からの距離
  }
  
  
  // カット情報
  Vec3r p[5];
  Vec3r base;  // セルのシフト量
  Vec3r b;     // セルセンタ座標
  REAL_TYPE lb[5]; // 内外判定フラグ
  
  for (int k=1; k<=kx; k++) {
    for (int j=box_st.y-1; j<=box_ed.y+1; j++) {
      for (int i=box_st.x-1; i<=box_ed.x+1; i++) {
        
        REAL_TYPE z = org.z + 0.5*dz + dz*(REAL_TYPE)(k-1);
        
        if ( z <= ze )
        {
          base.assign((REAL_TYPE)i-0.5, (REAL_TYPE)j-0.5, (REAL_TYPE)k-0.5);
          b = org + base*pch;
          
          p[0].assign(b.x   , b.y   , b.z   ); // p
          p[1].assign(b.x-dx, b.y   , b.z   ); // w
          p[2].assign(b.x+dx, b.y   , b.z   ); // e
          p[3].assign(b.x   , b.y-dy, b.z   ); // s
          p[4].assign(b.x   , b.y+dy, b.z   ); // n
          
          // (cx, cy, *)が球の中心
          for (int l=0; l<5; l++) {
            REAL_TYPE x = p[l].x - cx;
            REAL_TYPE y = p[l].y - cy;
            REAL_TYPE rr = sqrt(x*x + y*y);
            lb[l] = ( rr <= rs ) ? -1.0 : 1.0; // 内側がマイナス
          }
          
          // cut test  注意! インデクスが1-4
          for (int l=1; l<=4; l++)
          {
            if ( lb[0]*lb[l] < 0.0 )
            {
              REAL_TYPE s = cut_line_2d(p[0], l, rs);
              size_t m = _F_IDX_S3D(i, j, k, ix, jx, kx, gd);
              
              int r = quantize9(s);

              setCut9(cut[m], r, l-1);
              setBit5(bid[m], mid_s, l-1);
              
              int rr = quantize9(1.0-s);

              size_t m1;
              
              switch (l-1) {
                case X_minus:
                  m1 = _F_IDX_S3D(i-1, j, k, ix, jx, kx, gd);
                  setBit5(bid[m1], mid_s, X_plus);
                  setCut9(cut[m1], rr, X_plus);
                  break;
                  
                case X_plus:
                  m1 = _F_IDX_S3D(i+1, j, k, ix, jx, kx, gd);
                  setBit5(bid[m1], mid_s, X_minus);
                  setCut9(cut[m1], rr, X_minus);
                  break;
                  
                case Y_minus:
                  m1 = _F_IDX_S3D(i, j-1, k, ix, jx, kx, gd);
                  setBit5(bid[m1], mid_s, Y_plus);
                  setCut9(cut[m1], rr, Y_plus);
                  break;
                  
                case Y_plus:
                  m1 = _F_IDX_S3D(i, j+1, k, ix, jx, kx, gd);
                  setBit5(bid[m1], mid_s, Y_minus);
                  setCut9(cut[m1], rr, Y_minus);
                  break;
              }

            }
          }
        } // if z branch

      }
    }
  }
  
  if ( mode == dim_2d ) return;

  
  // Z+方向
#pragma omp parallel for firstprivate(ix, jx, kx, gd, mid_s, ox, oy, oz, dx, dy, dz, ze, rs, cx, cy) 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 y = oy + 0.5*dy + dy*(j-1);
        REAL_TYPE z = oz + 0.5*dz + dz*(k-1);
        REAL_TYPE s = (ze - z)/dz;
        
        REAL_TYPE xx = x - cx;
        REAL_TYPE yy = y - cy;
        
        if ( (xx*xx + yy*yy) <= rs*rs )
        {
          
          if ( (z <= ze) && (ze < z+dz) )
          {
            setBit5(bid[m], mid_s, Z_plus);
            int r = quantize9(s);
            setCut9(cut[m], r, Z_plus);

            size_t m1 = _F_IDX_S3D(i, j, k+1, ix, jx, kx, gd);
            setBit5(bid[m1], mid_s, Z_minus);
            int rr = quantize9(1.0-s);
            setCut9(cut[m1], rr, Z_minus);
          }
          else if ( (z-dz < ze) && (ze < z) )
          {
            setBit5(bid[m], mid_s, Z_minus);
            int r = quantize9(-s);
            setCut9(cut[m], r, Z_minus);

            size_t m1 = _F_IDX_S3D(i, j, k-1, ix, jx, kx, gd);
            setBit5(bid[m1], mid_s, Z_plus);
            int rr = quantize9(1.0+s);
            setCut9(cut[m1], rr, Z_plus);
          }
          
        }
        
      }
    }
  }

  
  // Z-方向
#pragma omp parallel for firstprivate(ix, jx, kx, gd, mid_s, ox, oy, oz, dx, dy, dz, zs, rs, cx, cy) 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 y = oy + 0.5*dy + dy*(j-1);
        REAL_TYPE z = oz + 0.5*dz + dz*(k-1);
        REAL_TYPE s = (zs - z)/dz;
        
        REAL_TYPE xx = x - cx;
        REAL_TYPE yy = y - cy;
        
        if ( (xx*xx + yy*yy) <= rs*rs )
        {
          
          if ( (z <= zs) && (zs < z+dz) )
          {
            setBit5(bid[m], mid_s, Z_plus);
            int r = quantize9(s);
            setCut9(cut[m], r, Z_plus);
            
            size_t m1 = _F_IDX_S3D(i, j, k+1, ix, jx, kx, gd);
            setBit5(bid[m1], mid_s, Z_minus);
            int rr = quantize9(1.0-s);
            setCut9(cut[m1], rr, Z_minus);
          }
          else if ( (z-dz < zs) && (zs < z) )
          {
            setBit5(bid[m], mid_s, Z_minus);
            int r = quantize9(-s);
            setCut9(cut[m], r, Z_minus);
            
            size_t m1 = _F_IDX_S3D(i, j, k-1, ix, jx, kx, gd);
            setBit5(bid[m1], mid_s, Z_plus);
            int rr = quantize9(1.0+s);
            setCut9(cut[m1], rr, Z_plus);
          }
          
        }
        
      }
    }
  }
  
  
}