IGMBaseLib 1.0
|
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