예제 #1
0
파일: ffv.C 프로젝트: kawada-atsushi/FFVC
/**
 * @brief 派生変数のファイル出力
 * @param [in,out] flop       浮動小数点演算数
 * @note d_p0をワークとして使用
 */
void FFV::OutputDerivedVariables(double& flop)
{
  REAL_TYPE scale = 1.0;
  
  // ステップ数
  unsigned m_step = (unsigned)CurrentStep;
  
  // 時間の次元変換
  REAL_TYPE m_time;
  if (C.Unit.File == DIMENSIONAL)
  {
    m_time = (REAL_TYPE)(CurrentTime * C.Tscale);
  }
  else
  {
    m_time = (REAL_TYPE)CurrentTime;
  }
  
  // ガイドセル出力
  int gc_out = C.GuideOut;
  
  
  // 最大値と最小値
  REAL_TYPE f_min, f_max, min_tmp, max_tmp, vec_min[4], vec_max[4];
  REAL_TYPE minmax[2];
  REAL_TYPE cio_minmax[8];
  
  
  // エラーコード
  CIO::E_CIO_ERRORCODE ret;
  
  
  REAL_TYPE unit_velocity = (C.Unit.File == DIMENSIONAL) ? C.RefVelocity : 1.0;
  
  
  // Total Pressure
  if (C.varState[var_TotalP] == ON )
  {
    fb_totalp_ (d_p0, size, &guide, d_v, d_p, v00, &flop);
    
    // convert non-dimensional to dimensional, iff file is dimensional
    if (C.Unit.File == DIMENSIONAL)
    {
      U.convArrayTpND2D(d_ws, d_p0, size, guide, C.RefDensity, C.RefVelocity);
    }
    else
    {
      REAL_TYPE* tp;
      tp = d_ws; d_ws = d_p0; d_p0 = tp;
    }
    
    fb_minmax_s_ (&f_min, &f_max, size, &guide, d_ws, &flop);
    
    if ( numProc > 1 )
    {
      min_tmp = f_min;
      if( paraMngr->Allreduce(&min_tmp, &f_min, 1, MPI_MIN) != CPM_SUCCESS ) Exit(0);
      
      max_tmp = f_max;
      if( paraMngr->Allreduce(&max_tmp, &f_max, 1, MPI_MAX) != CPM_SUCCESS ) Exit(0);
    }
    minmax[0] = f_min;
    minmax[1] = f_max;
    
    if ( !DFI_OUT_TP )
    {
      printf("[%d] DFI_OUT_TP Pointer Error\n",paraMngr->GetMyRankID());
      Exit(-1);
    }
    
    ret = DFI_OUT_TP->WriteData(m_step,
                                m_time,
                                size,
                                1,
                                guide,
                                d_ws,
                                minmax,
                                true,
                                0,
                                0.0);

    if ( ret != CIO::E_CIO_SUCCESS ) Exit(0);
  }
  
  
  // Vorticity
  if (C.varState[var_Vorticity] == ON )
  {
    rot_v_(d_wv, size, &guide, &deltaX, d_v, d_cdf, v00, &flop);
    
    REAL_TYPE  vz[3];
    vz[0] = vz[1] = vz[2] = 0.0;
    unit_velocity = (C.Unit.File == DIMENSIONAL) ? C.RefVelocity/C.RefLength : 1.0;
    
    if ( DFI_OUT_VRT->GetArrayShape() == CIO::E_CIO_NIJK ) // Vorticityの型は CIO::E_CIO_NIJK
    {
      fb_vout_nijk_(d_wo, d_wv, size, &guide, vz, &unit_velocity, &flop);
      fb_minmax_vex_ (vec_min, vec_max, size, &guide, v00, d_wo, &flop);
    }
    else 
    {
      fb_vout_ijkn_(d_wo, d_wv, size, &guide, vz, &unit_velocity, &flop);
      fb_minmax_v_ (vec_min, vec_max, size, &guide, v00, d_wo, &flop);
    }
    
    if ( numProc > 1 )
    {
      REAL_TYPE vmin_tmp[4] = {vec_min[0], vec_min[1], vec_min[2], vec_min[3]};
      if( paraMngr->Allreduce(vmin_tmp, vec_min, 4, MPI_MIN) != CPM_SUCCESS ) Exit(0);
      
      REAL_TYPE vmax_tmp[4] = {vec_max[0], vec_max[1], vec_max[2], vec_max[3]};
      if( paraMngr->Allreduce(vmax_tmp, vec_max, 4, MPI_MAX) != CPM_SUCCESS ) Exit(0);
    }
    
    if ( !DFI_OUT_VRT )
    {
      printf("[%d] DFI_OUT_VRT Pointer Error\n", paraMngr->GetMyRankID());
      Exit(-1);
    }
    
    cio_minmax[0] = vec_min[1]; ///<<< vec_u min
    cio_minmax[1] = vec_max[1]; ///<<< vec_u max
    cio_minmax[2] = vec_min[2]; ///<<< vec_v min
    cio_minmax[3] = vec_max[2]; ///<<< vec_v max
    cio_minmax[4] = vec_min[3]; ///<<< vec_w min
    cio_minmax[5] = vec_max[3]; ///<<< vec_w max
    cio_minmax[6] = vec_min[0]; ///<<< u,v,wの合成値のmin
    cio_minmax[7] = vec_max[0]; ///<<< u,v,wの合成値のmax

    ret = DFI_OUT_VRT->WriteData(m_step,
                                 m_time,
                                 size,
                                 3,
                                 guide,
                                 d_wo,
                                 cio_minmax,
                                 true,
                                 0,
                                 0.0);

    if ( ret != CIO::E_CIO_SUCCESS ) Exit(0);
  }
  
  
  // 2nd Invariant of Velocity Gradient Tensor
  if (C.varState[var_Qcr] == ON )
  {
    i2vgt_ (d_p0, size, &guide, &deltaX, d_v, d_cdf, v00, &flop);
    
    // 無次元で出力
    U.copyS3D(d_ws, size, guide, d_p0, scale);
    
    fb_minmax_s_ (&f_min, &f_max, size, &guide, d_ws, &flop);
    
    if ( numProc > 1 )
    {
      min_tmp = f_min;
      if( paraMngr->Allreduce(&min_tmp, &f_min, 1, MPI_MIN) != CPM_SUCCESS ) Exit(0);
      
      max_tmp = f_max;
      if( paraMngr->Allreduce(&max_tmp, &f_max, 1, MPI_MAX) != CPM_SUCCESS ) Exit(0);
    }
    minmax[0] = f_min;
    minmax[1] = f_max;
    
    if ( !DFI_OUT_I2VGT )
    {
      printf("[%d] DFI_OUT_I2VGT Pointer Error\n", paraMngr->GetMyRankID());
      Exit(-1);
    }
    
    ret = DFI_OUT_I2VGT->WriteData(m_step,
                                   m_time,
                                   size,
                                   1,
                                   guide,
                                   d_ws,
                                   minmax,
                                   true,
                                   0,
                                   0.0);

    if( ret != CIO::E_CIO_SUCCESS ) Exit(0);
  }
  
  
  // Helicity
  if (C.varState[var_Helicity] == ON )
  {
    helicity_(d_p0, size, &guide, &deltaX, d_v, d_cdf, v00, &flop);
    
    // 無次元で出力
    U.copyS3D(d_ws, size, guide, d_p0, scale);
    
    fb_minmax_s_ (&f_min, &f_max, size, &guide, d_ws, &flop);
    
    if ( numProc > 1 )
    {
      min_tmp = f_min;
      if( paraMngr->Allreduce(&min_tmp, &f_min, 1, MPI_MIN) != CPM_SUCCESS ) Exit(0);
      
      max_tmp = f_max;
      if( paraMngr->Allreduce(&max_tmp, &f_max, 1, MPI_MAX) != CPM_SUCCESS ) Exit(0);
    }
    minmax[0] = f_min;
    minmax[1] = f_max;
    
    if ( !DFI_OUT_HLT )
    {
      printf("[%d] DFI_OUT_HLT Pointer Error\n", paraMngr->GetMyRankID());
      Exit(-1);
    }
    
    ret = DFI_OUT_HLT->WriteData(m_step,
                                 m_time,
                                 size,
                                 1,
                                 guide,
                                 d_ws,
                                 minmax,
                                 true,
                                 0,
                                 0.0);

    if( ret != CIO::E_CIO_SUCCESS ) Exit(0);
  }
}
예제 #2
0
파일: ffv_Loop.C 프로젝트: VisCore618/FFVC
// タイムステップループの処理
int FFV::Loop(const unsigned step) 
{
  // 1 step elapse (sec)
  double step_start = cpm_Base::GetWTime();
  double step_end;
  
  double flop_count=0.0;   /// 浮動小数演算数
  double avr_Var[3];       /// 平均値(速度、圧力、温度)
  double rms_Var[3];       /// 変動値
  REAL_TYPE vMax=0.0;      /// 最大速度成分

  
  // Loop section
  TIMING_start(tm_loop_sct);
  
  // 時間進行
  CurrentTime += DT.get_DT(); // 戻り値はdouble
  CurrentStep++;
  
  
  // 参照座標速度をv00に保持する
  copyV00fromRF(CurrentTime);
  
  // モニタークラスに参照速度を渡す
  if (C.SamplingMode == ON) MO.setV00(v00);
  
  // 速度成分の最大値
  TIMING_start(tm_vmax);
  flop_count = 0.0;
  find_vmax_(&vMax, size, &guide, v00, d_v, &flop_count);
  TIMING_stop(tm_vmax, flop_count);
  
  if ( numProc > 1 ) 
  {
    TIMING_start(tm_vmax_comm);
    REAL_TYPE vMax_tmp = vMax;
    if ( paraMngr->Allreduce(&vMax_tmp, &vMax, 1, MPI_MAX) != CPM_SUCCESS ) Exit(0);
    TIMING_stop( tm_vmax_comm, 2.0*numProc*sizeof(REAL_TYPE) ); // 双方向 x ノード数
  }
  
  
  // Flow
  if ( C.KindOfSolver != SOLID_CONDUCTION )
  {
    TIMING_start(tm_flow_sct);
    
    switch (C.AlgorithmF) 
    {
      case Flow_FS_EE_EE:
      case Flow_FS_AB2:
      case Flow_FS_AB_CN:
        if (C.Mode.ShapeAprx == BINARY)
        {
          NS_FS_E_Binary();
        }
        else if (C.Mode.ShapeAprx == CUT_INFO)
        {
          NS_FS_E_CDS();
        }          
        break;
        
      case Flow_FS_RK_CN:
        break;
        
      default:
        break;
    }
    TIMING_stop(tm_flow_sct, 0.0);
  }
  
  // Heat
  if ( C.isHeatProblem() ) 
  {
    TIMING_start(tm_heat_sct);
    PS_Binary();
    TIMING_stop(tm_heat_sct, 0.0);
  }
  
  
  
  // Interface Equation
  if ( C.BasicEqs == INCMP_2PHASE ) 
  {
    TIMING_start(tm_vof_sct);
    //IF_TRP_VOF();
    TIMING_stop(tm_vof_sct, 0.0);
  }
  
  
  
  // >>> ステップループのユーティリティ
  TIMING_start(tm_loop_uty_sct);
  
  //  >>> ステップループのユーティリティ 1
  TIMING_start(tm_loop_uty_sct_1);
  
  // 時間平均値操作
  if ( (C.Mode.Average == ON) && C.Interval[Control::tg_average].isStarted(CurrentStep, CurrentTime))
  {
    TIMING_start(tm_average_time);
    flop_count=0.0;
    Averaging(flop_count);
    TIMING_stop(tm_average_time, flop_count);
  }
  
  // 空間平均値操作と変動量
  TIMING_start(tm_stat_space);
  flop_count=0.0;
  for (int i=0; i<3; i++) 
  {
    avr_Var[i] = 0.0;
    rms_Var[i] = 0.0;
  }
  VariationSpace(avr_Var, rms_Var, flop_count);
  TIMING_stop(tm_stat_space, flop_count);

  
  
  if ( numProc > 1 ) 
  {
    /// var_Velocity=0,  > FB_Define.h
    /// var_Pressure,
    /// var_Temperature,
    double src[6], dst[6]; // Vel, Prs, Tempで3*2
    TIMING_start(tm_stat_space_comm);
    
    for (int n=0; n<3; n++) {
      src[n]   = avr_Var[n];
      src[n+3] = rms_Var[n];
    }
    
    if ( paraMngr->Allreduce(src, dst, 6, MPI_SUM) != CPM_SUCCESS) Exit(0); // 変数 x (平均値+変動値)
    
    for (int n=0; n<3; n++) {
      avr_Var[n] = dst[n];
      rms_Var[n] = dst[n+3];
    }
    
    TIMING_stop(tm_stat_space_comm, 2.0*numProc*6.0*2.0*sizeof(double) ); // 双方向 x ノード数 x 変数
  }

  avr_Var[var_Velocity] /= (double)G_Acell;  // 速度の空間平均
  avr_Var[var_Pressure] /= (double)G_Acell;  // 圧力の空間平均
  
  rms_Var[var_Velocity] /= (double)G_Acell;  // 速度の変動量
  rms_Var[var_Pressure] /= (double)G_Acell;  // 圧力の変動量
  rms_Var[var_Velocity] = sqrt(rms_Var[var_Velocity]);
  rms_Var[var_Pressure] = sqrt(rms_Var[var_Pressure]);
  
  if ( C.isHeatProblem() ) 
  {
    avr_Var[var_Temperature] /= (double)G_Acell;   // 温度の空間平均
    rms_Var[var_Temperature] /= (double)G_Acell;   // 温度の変動量
    rms_Var[var_Temperature] = sqrt(rms_Var[var_Temperature]);
  }
  
  //  <<< ステップループのユーティリティ 1
  TIMING_stop(tm_loop_uty_sct_1, 0.0);
  
  
  
  // 1ステップ後のモニタ処理 -------------------------------
  
  //  >>> ステップループのユーティリティ 2
  TIMING_start(tm_loop_uty_sct_2);
  
  // Historyクラスのタイムスタンプを更新
  H->updateTimeStamp(CurrentStep, (REAL_TYPE)CurrentTime, vMax);
  
  
  
  // 瞬時値のデータ出力

  if ( C.Hide.PM_Test == OFF )
  {
    // 通常
    if ( C.Interval[Control::tg_basic].isTriggered(CurrentStep, CurrentTime) )
    {
      TIMING_start(tm_file_out);
      flop_count=0.0;
      OutputBasicVariables(flop_count);
      TIMING_stop(tm_file_out, flop_count);
    }
    
    if ( C.Interval[Control::tg_derived].isTriggered(CurrentStep, CurrentTime) )
    {
      TIMING_start(tm_file_out);
      flop_count=0.0;
      OutputDerivedVariables(flop_count);
      TIMING_stop(tm_file_out, flop_count);
    }
    
    // 最終ステップ
    if ( C.Interval[Control::tg_compute].isLast(CurrentStep, CurrentTime) )
    {
      // 指定間隔の出力がない場合のみ(重複を避ける)
      if ( !C.Interval[Control::tg_basic].isTriggered(CurrentStep, CurrentTime) )
      {
        TIMING_start(tm_file_out);
        flop_count=0.0;
        OutputBasicVariables(flop_count);
        TIMING_stop(tm_file_out, flop_count);
      }
      
      if ( !C.Interval[Control::tg_derived].isTriggered(CurrentStep, CurrentTime) )
      {
        TIMING_start(tm_file_out);
        flop_count=0.0;
        OutputDerivedVariables(flop_count);
        TIMING_stop(tm_file_out, flop_count);
      }
    }
    
  }

  
  // 平均値のデータ出力 
  if (C.Mode.Average == ON) 
  {
    
    // 開始時刻を過ぎているか
    if ( C.Interval[Control::tg_average].isStarted(CurrentStep, CurrentTime) )
    {
      // 通常
      if ( C.Interval[Control::tg_average].isTriggered(CurrentStep, CurrentTime) ) 
      {
        TIMING_start(tm_file_out);
        flop_count=0.0;
        OutputAveragedVarables(flop_count);
        TIMING_stop(tm_file_out, flop_count);
      }
      
      // 最終ステップ
      if ( C.Interval[Control::tg_compute].isLast(CurrentStep, CurrentTime) )
      {
        // 指定間隔の出力がない場合のみ(重複を避ける)
        if ( !C.Interval[Control::tg_average].isTriggered(CurrentStep, CurrentTime) )
        {
          TIMING_start(tm_file_out);
          flop_count=0.0;
          OutputAveragedVarables(flop_count);
          TIMING_stop(tm_file_out, flop_count);
        }
      }
    }
  }
  
  if (C.varState[var_TotalP] == ON )
  {
    TIMING_start(tm_total_prs);
    flop_count=0.0;
    fb_totalp_ (d_p0, size, &guide, d_v, d_p, v00, &flop_count);
    TIMING_stop(tm_total_prs, flop_count);
  }
  

  
  // サンプリング履歴
  if ( (C.SamplingMode == ON) && C.Interval[Control::tg_sampled].isTriggered(CurrentStep, CurrentTime) )
  {
    TIMING_start(tm_sampling);
    MO.sampling();
    TIMING_stop(tm_sampling, 0.0);

    TIMING_start(tm_hstry_sampling);
    MO.print(CurrentStep, (REAL_TYPE)CurrentTime);
    TIMING_stop(tm_hstry_sampling, 0.0);
  }

  
  
  // 1 step elapse
  step_end = cpm_Base::GetWTime() - step_start;
  
  
  // 基本履歴情報をコンソールに出力
  if ( C.Mode.Log_Base == ON)
  {
    if ( C.Interval[Control::tg_console].isTriggered(CurrentStep, CurrentTime) )
    {
      TIMING_start(tm_hstry_stdout);
      Hostonly_
      {
        H->printHistory(stdout, avr_Var, rms_Var, IC, &C, step_end, true);
        
        if ( C.Mode.CCNV == ON )
        {
          H->printCCNV(avr_Var, rms_Var, IC, &C, step_end);
        }
      }
      TIMING_stop(tm_hstry_stdout, 0.0);
    }
  }