IGMBaseLib 1.0

src/io/netcdf/IcGrid_ncReader_mod.f90

Go to the documentation of this file.
00001 
00022 module IcGrid_ncReader_mod
00023 
00024   ! モジュール引用 ; Use statements
00025   !
00026 
00027   ! 種類型パラメタ
00028   ! Kind type parameter
00029   !
00030   use dc_types, only: DP, &        ! 倍精度実数型. Double precision.
00031     &                 TOKEN, &
00032     &                 STRING
00033 
00034   ! メッセージ出力
00035   ! Message dump
00036   !
00037   use dc_message, only: &
00038     & MessageNotify
00039 
00040   ! 正二十面体格子データの管理
00041   ! Manager of icosahedral grid data
00042   !
00043   use IcGrid2D_FVM_Manager, only: &
00044     & IcGrid2D_FVM, &
00045     & paste_margin_width, &
00046     & get_EffSize_Min, get_EffSize_Max, get_IcRadius, &
00047     & RC_REGIONS_NUM
00048 
00049 
00050   ! 正二十面体格子上の物理場データの管理
00051   ! Manager of the physical field data on icosahedral grid
00052   !
00053   use Field_IcGrid2D_Manager, only: &
00054     & Field_IcGrid2D, paste_field_margin, &
00055     & set_long_field2D_name, set_field2D_units
00056 
00057 
00058   ! 非構造格子データモデルの構造型の提供
00059   ! Providing the derived types for unstructured grid data model
00060   !
00061   use IcGrid_ncStream_helper, only: &
00062     & Mesh2_ncInfo, Mesh2_ncInfo_Init, &
00063     & Mesh_dim_element, &
00064     & Mesh_coord_element, Mesh_coord_element_Init, &
00065     & check_nf90_status
00066 
00067   ! NetCDF
00068   !
00069   !
00070   use netcdf
00071 
00072   ! 宣言文 ; Declaration statements
00073   !
00074   implicit none
00075   private
00076 
00077   !
00087   type, public :: IcGrid_ncReader
00088     ! 公開メンバー変数
00089     ! Public member variable
00090     !
00091 
00094     integer :: ncID
00095 
00098     type(Mesh2_ncInfo) :: mesh2Info
00099 
00102     type(IcGrid2D_FVM), pointer :: icgrid
00103 
00104   end type IcGrid_ncReader
00105 
00106   ! 公開手続き
00107   ! Public procedures
00108   !
00109   public :: IcGrid_ncReader_Init
00110   public :: open_ncFile, read_Simulation_Parameter, read_GridData, read_FieldData, close_ncFile
00111 
00112   ! interface 文; interface statements
00113   !
00114   !
00115   interface IcGrid_ncReader_Init
00116     module procedure IcGrid2D_ncReader_Init
00117   end interface IcGrid_ncReader_Init
00118 
00119   interface read_FieldData
00120     module procedure read_Field2D_Data
00121   end interface read_FieldData
00122 
00123 contains
00124 
00125 !
00142 subroutine IcGrid2D_ncReader_Init( &
00143   & self,                        & ! (inout)
00144   & ref_icgrid )                   ! (in)
00145 
00146   ! 宣言文 ; Declaration statements
00147   !
00148 
00149   type(IcGrid_ncReader), intent(inout) :: self
00150   type(IcGrid2D_FVM), intent(in), target :: ref_icgrid
00151 
00152   ! 作業変数
00153   ! Work variables
00154   !
00155 
00156   ! 実行文 ; Executable statements
00157   !
00158 
00159   self%icgrid => ref_icgrid
00160 
00161   ! 構造型 Mesh2_Info の変数を初期化する.
00162   call Mesh2_ncInfo_Init(self%mesh2Info, self%icgrid)
00163 
00164 end subroutine IcGrid2D_ncReader_Init
00165 
00166 !
00185 subroutine open_ncFile( &
00186   & self,               & ! (inout)
00187   & file_name )           ! (in)
00188 
00189   ! 宣言文 ; Declaration statements
00190   !
00191   type(IcGrid_ncReader), intent(inout) :: self
00192   character(*), intent(in) :: file_name
00193 
00194   ! 実行文 ; Executable statement
00195   !
00196 
00197   ! netCDF ファイルの作成
00198   call check_nf90_status( &
00199     & nf90_open(file_name, NF90_NOWRITE, self%ncID),  &
00200     & message='open netCDF file `' // trim(file_name) //  '`' )
00201 
00202   ! Mesh2 の次元要素である node (節) に対応する次元 ID を netCDF ファイルから取得する.
00203   call check_nf90_status( &
00204     & nf90_inq_dimid(self%ncID, self%mesh2Info%node%element_name, self%mesh2Info%node%dimID), &
00205     & message='read dimension information from netCDF file' )
00206 
00207   ! Mesh2 の次元要素である node (節) の総数を netCDF ファイルから取得する.
00208   call check_nf90_status( &
00209     & nf90_inquire_dimension(self%ncID, self%mesh2Info%node%dimID, len=self%mesh2Info%node%num) &
00210     & )
00211 
00212 end subroutine open_ncFile
00213 
00214 !
00231 subroutine read_Simulation_Parameter( &
00232   & self,                                    &  ! (inout)
00233   & integration_time, time_step, output_tick &  ! (in)
00234   & )
00235 
00236   ! 宣言文 ; Declaration statements
00237   !
00238   type(IcGrid_ncReader), intent(inout) :: self
00239   real(DP), intent(out) :: integration_time
00240   real(DP), intent(out) :: time_step
00241   real(DP), intent(out) :: output_tick
00242 
00243   ! 実行文 ; Executable statements
00244   !
00245 
00246   ! 各シミュレーションパラメータのデータを, NetCDF のグローバル領域から読み込む.
00247   call check_nf90_status( &
00248     & nf90_get_att(self%ncID, NF90_GLOBAL, 'integration_time', integration_time) &
00249     & )
00250 
00251   call check_nf90_status( &
00252     & nf90_get_att(self%ncID, NF90_GLOBAL, 'time_step', time_step) &
00253     & )
00254 
00255   call check_nf90_status( &
00256     & nf90_get_att(self%ncID, NF90_GLOBAL, 'output_tick', output_tick) &
00257     & )
00258 
00259 
00260 end subroutine read_Simulation_Parameter
00261 
00262 !
00273 subroutine read_GridData( &
00274   & self )                  ! (inout)
00275 
00276   ! モジュール引用 ; Use statement
00277   !
00278 
00279   ! 座標変換
00280   ! Coordinate conversion
00281   !
00282   use igmcore_coordinate_conversion, only: &
00283     & geo_to_orth_pos
00284 
00285   ! 宣言文 ; Declaration statements
00286   !
00287   type(IcGrid_ncReader), intent(inout) :: self
00288 
00289   ! 作業変数
00290   ! Work variable
00291   !
00292   real(DP), allocatable :: s_rcs_node_x(:), s_rcs_node_y(:)
00293   integer :: rcs_AGrid_shape(3)
00294   integer :: rcID, i,j
00295   real(DP) :: radius
00296   integer :: EMax, EMin, EffSize
00297 
00298   ! 実行文 ; Executable statements
00299   !
00300 
00301   ! 正二十面格子の矩形領域の配列のインデックス情報を取得する.
00302   EMin = get_EffSize_Min(self%icgrid)
00303   EMax = get_EffSize_Max(self%icgrid)
00304   EffSize = EMax - EMin + 1
00305 
00306   ! 格子の経度・緯度についての情報を保持している Mesh2_node_x, Mesh2_node_y を読み込み,
00307   ! 緯度経度座標データのままひとまず構造体 IcGrid2D_FVM の変数に保存する.
00308   !
00309 
00310   allocate( s_rcs_node_x(self%Mesh2Info%node%num) )
00311   allocate( s_rcs_node_y(self%Mesh2Info%node%num) )
00312 
00313 !  write(*,*) 'reading mesh coordinate data from netCDF...'
00314 
00315   ! Mesh2_node_x, Mesh2_node_y の変数 ID を取得する.
00316   call check_nf90_status( &
00317     & nf90_inq_varid(self%ncID, self%mesh2Info%node_x%element_name, self%mesh2Info%node_x%varID) &
00318     & )
00319   call check_nf90_status( &
00320     & nf90_inq_varid(self%ncID, self%mesh2Info%node_y%element_name, self%mesh2Info%node_y%varID) &
00321     & )
00322 
00323   ! Mesh2_node_x, Mesh2_node_y のデータを読み込み, 作業用の 1 次元配列に取り込む
00324   call check_nf90_status( &
00325     & nf90_get_var(self%ncID, self%mesh2Info%node_x%varID, s_rcs_node_x) &
00326     & )
00327 
00328   call check_nf90_status( &
00329     & nf90_get_var(self%ncID, self%mesh2Info%node_y%varID, s_rcs_node_y) &
00330     & )
00331 
00332   ! 1 次元配列に格納した格子の経度・緯度の座標データを, 構造体 IcGrid2D_FVM の成分 rcs_AGrid に格納する.
00333   ! この際, 読み込んだ配列データの形状を変換する.
00334   radius = get_IcRadius(self%icgrid)
00335   rcs_AGrid_shape = shape(self%icgrid%rcs_AGrid(:,EMin:EMax,EMin:EMax,1))
00336   self%icgrid%rcs_AGrid(:,EMin:EMax,EMin:EMax,1) = reshape( s_rcs_node_x, rcs_AGrid_shape )
00337   self%icgrid%rcs_AGrid(:,EMin:EMax,EMin:EMax,2) = reshape( s_rcs_node_y, rcs_AGrid_shape )
00338   self%icgrid%rcs_AGrid(:,EMin:EMax,EMin:EMax,3) = radius
00339 
00340   ! rcs_AGrid に格納した格子位置に関する緯度経度座標データを, デカルト座標データに変換する.
00341   !
00342 
00343   do rcID=1, RC_REGIONS_NUM
00344     do j=EMin, EMax
00345       do i=EMin, EMax
00346         !
00347         if ( rcID <= 5 .and. i==EMin .and. j==EMin ) then
00348           self%icgrid%rcs_AGrid(rcID, i,j, :) = (/ 0.0d0, 0.0d0, radius /)
00349 
00350         else if( rcID > 5 .and. i==EMax .and. j==EMax ) then
00351           self%icgrid%rcs_AGrid(rcID, i,j, :) = (/ 0.0d0, 0.0d0, -radius /)
00352 
00353         else
00354           self%icgrid%rcs_AGrid(rcID, i,j, :) = geo_to_orth_pos( self%icgrid%rcs_AGrid(rcID,i,j,:) )
00355         end if
00356 
00357       end do
00358     end do
00359   end do
00360 
00361   ! のりしろを貼り合わせる
00362   call paste_margin_width(self%icgrid)
00363 
00364 end subroutine read_GridData
00365 
00366 !
00383 subroutine read_Field2D_Data(&
00384   & self,                 & ! (in)
00385   & name,                 & ! (in)
00386   & field,                & ! (inout)
00387   & time_level )            ! (in)
00388 
00389   ! 宣言文 ; Declaration statements
00390   !
00391   type(IcGrid_ncReader), intent(in) :: self
00392   character(*), intent(in) :: name
00393   type(Field_IcGrid2D), intent(inout) :: field
00394   integer, intent(in) :: time_level
00395 
00396   ! 作業変数
00397   ! Work variables
00398   !
00399   integer :: field_shape(3)
00400   integer :: varID
00401 
00402   integer :: EMax, EMin
00403   real(DP), allocatable :: field_temp(:)
00404   character(STRING) :: long_name
00405   character(TOKEN) :: units
00406 
00407 
00408   ! 実行文 ; Executable statement
00409   !
00410 
00411   ! 正二十面格子の矩形領域の配列のインデックス情報を取得する.
00412   EMin = get_EffSize_Min(self%icgrid)
00413   EMax = get_EffSize_Max(self%icgrid)
00414 
00415   ! 一次元化された二次元物理場データを NetCDF から読み込むときに,
00416   ! 一時的にそのデータを格納するための作業配列のメモリを確保する.
00417   allocate( field_temp(self%Mesh2Info%node%num) )
00418 
00419   ! 読み出す物理場変数に対応する NetCDF における変数 ID を取得する.
00420   call check_nf90_status( &
00421     & nf90_inq_varid(self%ncID, name, varID), &
00422     & message='inqure variable ID: ' //  trim(name) )
00423 
00424   ! 時間レベル time_level の一次元化された二次元物理場データを読み込み, 作業配列に取り込む.
00425   call check_nf90_status( &
00426     & nf90_get_var(self%ncID, varID, field_temp, &
00427         & start=(/ 1, time_level /), count=(/ self%Mesh2Info%node%num, 1 /) ), &
00428     & message='get variable: ' // trim(name) )
00429 
00430   ! 物理場の長い名前を取得する.
00431   call check_nf90_status( &
00432     & nf90_get_att(self%ncID, varID, "long_name", long_name), &
00433     & message = 'get attribute: long_name' )
00434 
00435   ! 物理場の長い単位を取得する.
00436   call check_nf90_status( &
00437     & nf90_get_att(self%ncID, varID, "units", units), &
00438     & message = 'get attribute: units' )
00439 
00440   ! 一次元化された二次元物理場データを, 2 次元に戻す.
00441   field_shape = shape(self%icgrid%rcs_AGrid(:,EMin:EMax,EMin:EMax,1))
00442   field%val(:,EMin:EMax,EMin:EMax,1) = reshape( field_temp, field_shape )
00443 
00444   ! 読み込んだ物理場の長い名前・単位を Field_IcGrid2D の変数に設定する.
00445   call set_long_field2D_name(field, long_name)
00446   call set_field2D_units(field, units)
00447 
00448   ! 各矩形領域の袖領域部分を隣の矩形領域端のデータで埋める.
00449   call paste_field_margin(field)
00450 
00451 end subroutine read_Field2D_Data
00452 
00453 !
00464 subroutine close_ncFile(self)
00465 
00466   ! 宣言文 ; Declaration statements
00467   !
00468   type(IcGrid_ncReader), intent(in) :: self
00469 
00470   ! 実行文 ; Executable statement
00471   !
00472   call check_nf90_status( nf90_close(self%ncID) )
00473 
00474 end subroutine close_ncFile
00475 
00476 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00477 !
00478 ! 非公開手続き
00479 !
00480 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00481 
00482 end module IcGrid_ncReader_mod
 All Classes Namespaces Files Functions Variables