IGMBaseLib 1.0
|
00001 00022 module IcGrid_ncWriter_mod 00023 00024 ! モジュール引用 ; Use statements 00025 ! 00026 00027 ! 種類型パラメタ 00028 ! Kind type parameter 00029 ! 00030 use dc_types, only: DP, & ! 倍精度実数型. Double precision. 00031 & TOKEN 00032 00033 00034 ! 正二十面体格子データの管理 00035 ! Manager of icosahedral grid data 00036 ! 00037 use IcGrid2D_FVM_Manager, only: & 00038 & IcGrid2D_FVM, & 00039 & paste_margin_width, & 00040 & get_EffSize_Min, get_EffSize_Max, get_IcRadius, get_glevel, & 00041 & RC_REGIONS_NUM 00042 00043 00044 ! 正二十面体格子上の物理場データの管理 00045 ! Manager of the physical field data on icosahedral grid 00046 ! 00047 use Field_IcGrid2D_Manager, only: & 00048 & Field_IcGrid2D, & 00049 & get_field2D_name, get_long_field2D_name, get_field2D_units, get_Physical_Field 00050 00051 00052 ! 非構造格子データモデルの構造型の提供 00053 ! Providing the derived types for unstructured grid data model 00054 ! 00055 use IcGrid_ncStream_helper, only: & 00056 & Mesh2_ncInfo, Mesh2_ncInfo_Init, & 00057 & Mesh_dim_element, & 00058 & Mesh_coord_element, & 00059 & check_nf90_status 00060 00061 ! NetCDF 00062 ! 00063 ! 00064 use netcdf 00065 00066 ! 宣言文 ; Declaration statements 00067 ! 00068 implicit none 00069 private 00070 00076 type, public :: IcGrid_ncWriter 00077 ! 公開メンバ変数 00078 ! Public member varables 00079 00082 integer :: ncID 00083 00086 type(Mesh2_ncInfo) :: mesh2Info 00087 00090 type(IcGrid2D_FVM), pointer :: icgrid 00091 00094 integer :: rec_dimid 00095 00098 integer :: rec_counter 00099 00100 end type IcGrid_ncWriter 00101 00102 ! 公開手続き 00103 ! Public procedures 00104 ! 00105 public :: IcGrid_ncWriter_Init 00106 public :: open_ncFile, close_ncFile 00107 public :: end_ncdef, ncdef_GridData, ncdef_FieldData, ncdef_Simulation_Parameter, & 00108 & write_GridData, write_FieldData, increase_recorde_counter 00109 00110 ! interface 文; interface statements 00111 ! 00112 ! 00113 interface IcGrid_ncWriter_Init 00114 module procedure IcGrid2D_ncWriter_Init 00115 end interface IcGrid_ncWriter_Init 00116 00117 interface ncdef_FieldData 00118 module procedure ncdef_Field2D_Data 00119 end interface ncdef_FieldData 00120 00121 interface write_FieldData 00122 module procedure write_Field2D_Data 00123 end interface write_FieldData 00124 00125 ! 非公開変数 00126 ! Private variables 00127 ! 00128 00131 character(TOKEN), parameter :: RECODE_NAME = 'time' 00132 00133 contains 00134 00135 ! 00154 subroutine IcGrid2D_ncWriter_Init(self, ref_icgrid) 00155 00156 ! 宣言文 ; Declaration statements 00157 ! 00158 00159 type(IcGrid_ncWriter), intent(inout) :: self 00160 type(IcGrid2D_FVM), intent(in), target :: ref_icgrid 00161 00162 ! 作業変数 00163 ! Work variables 00164 ! 00165 00166 ! 実行文 ; Executable statements 00167 ! 00168 00169 self%icgrid => ref_icgrid 00170 00171 ! 00172 self%rec_counter = 1 00173 00174 ! 正二十面体格子のメッシュ情報を保持する Mesh2_ncInfo クラスのインスタンスを初期化 00175 call Mesh2_ncInfo_Init(self%mesh2Info, self%icgrid) 00176 00177 00178 end subroutine IcGrid2D_ncWriter_Init 00179 00180 ! 00193 subroutine open_ncFile(self, file_name) 00194 00195 ! 宣言文 ; Declaration statement 00196 ! 00197 type(IcGrid_ncWriter), intent(inout) :: self 00198 character(*), intent(in) :: file_name 00199 00200 ! 実行文 ; Execuatble statement 00201 ! 00202 00203 ! netCDF ファイルの作成 00204 call check_nf90_status( & 00205 & nf90_create(file_name, NF90_CLOBBER, self%ncID) ) 00206 00207 end subroutine open_ncFile 00208 00209 ! 00220 subroutine ncdef_GridData(self) 00221 00222 ! 宣言文 ; Declaration statement 00223 ! 00224 type(IcGrid_ncWriter), intent(inout) :: self 00225 00226 ! 実行文 ; Executable statement 00227 ! 00228 00229 ! NetCDF ファイルに次元要素 node を定義する. 00230 call ncdef_dimension(self, self%Mesh2Info%node ) 00231 00232 ! NetCDF ファイルに座標要素 : node_x, node_y を定義する. 00233 call ncdef_mesh_coordinate(self, self%mesh2Info%node_x ) 00234 call ncdef_mesh_coordinate(self, self%mesh2Info%node_y ) 00235 00236 ! NetCDF ファイルに時間座標を定義する. 00237 call check_nf90_status( & 00238 & nf90_def_dim(self%ncID, RECODE_NAME, NF90_UNLIMITED, self%rec_dimid), & 00239 message='define dimension.' & 00240 & ) 00241 00242 ! 正二十面格子の水平解像度を NetCDF のグローバル領域に書きこむ. 00243 call check_nf90_status( nf90_put_att( self%ncID, NF90_GLOBAL, 'glevel', get_glevel(self%icgrid)) ) 00244 00245 end subroutine ncdef_GridData 00246 00247 ! 00260 function ncdef_Field2D_Data(self, field_Rank1) result(varid) 00261 00262 ! 宣言文 ; Declaration statements 00263 ! 00264 type(IcGrid_ncWriter), intent(in) :: self 00265 type(Field_IcGrid2D), intent(in) :: field_Rank1 00266 integer varid 00267 00268 ! 作業変数 00269 ! Work variables 00270 ! 00271 integer :: dimids(2) 00272 00273 ! 実行文 ; Executable statement 00274 ! 00275 00276 ! 00277 dimids = (/ self%Mesh2Info%node%dimid, self%rec_dimid /) 00278 00279 ! NetCDF ファイルに, 後に物理場のデータを書き込むことになる物理場の情報を定義する. 00280 call check_nf90_status( & 00281 & nf90_def_var(self%ncID, get_field2D_name(field_Rank1), NF90_DOUBLE, dimids, varid), & 00282 message='Define the field `' // trim(get_field2D_name(field_Rank1)) // '`.' & 00283 & ) 00284 00285 ! 物理場の long_name を設定. 00286 call check_nf90_status( & 00287 & nf90_put_att( self%ncID, varid, 'long_name', get_long_field2D_name(field_Rank1) ) & 00288 & ) 00289 00290 ! 物理場の単位の設定. 00291 call check_nf90_status( & 00292 & nf90_put_att( self%ncID, varid, 'units', get_field2D_units(field_Rank1) ) & 00293 & ) 00294 00295 end function ncdef_Field2D_Data 00296 00297 ! 00314 subroutine ncdef_Simulation_Parameter( & 00315 & self, & 00316 & integration_time, time_step, output_tick & 00317 ) 00318 ! 宣言文 ; Declaration statements 00319 ! 00320 type(IcGrid_ncWriter), intent(in) :: self 00321 real(DP), intent(in) :: integration_time 00322 real(DP), intent(in) :: time_step 00323 real(DP), intent(in) :: output_tick 00324 00325 ! 実行文 ; Executable statement 00326 ! 00327 00328 ! 積分時間, 時間ステップ, 出力間隔の情報を NetCDF のグローバル領域に書きこむ. 00329 call check_nf90_status( nf90_put_att( self%ncID, NF90_GLOBAL, 'integration_time', integration_time) ) 00330 call check_nf90_status( nf90_put_att( self%ncID, NF90_GLOBAL, 'time_step', time_step) ) 00331 call check_nf90_status( nf90_put_att( self%ncID, NF90_GLOBAL, 'output_tick', output_tick) ) 00332 00333 end subroutine ncdef_Simulation_Parameter 00334 00335 ! 00346 subroutine end_ncdef(self) 00347 00348 ! 宣言文 ; Declaration statements 00349 ! 00350 type(IcGrid_ncWriter), intent(in) :: self 00351 00352 ! 実行文 ; Executable statement 00353 ! 00354 00355 call check_nf90_status( nf90_enddef( self%ncID ) ) 00356 00357 end subroutine end_ncdef 00358 00359 ! 00370 subroutine write_GridData(self) 00371 00372 use igmcore_coordinate_conversion, only: orth_to_geo_pos 00373 00374 ! 宣言文 ; Declaration statements 00375 ! 00376 type(IcGrid_ncWriter), intent(in) :: self 00377 00378 ! 作業変数 00379 ! Work variables 00380 ! 00381 integer rcID, i, j 00382 integer EMin, EMax 00383 real(DP), allocatable :: s_rcs_node_x(:), s_rcs_node_y(:) 00384 real(DP), allocatable :: s_rcs_AGrid(:,:,:,:) 00385 00386 ! 実行文 ; Executable statements 00387 ! 00388 00389 EMin = get_EffSize_Min(self%icgrid) 00390 EMax = get_EffSize_Max(self%icgrid) 00391 00392 ! 作業変数のメモリを確保する. 00393 allocate( s_rcs_AGrid(RC_REGIONS_NUM, EMin:EMax, EMin:EMax, 3) ) 00394 allocate( s_rcs_node_x(self%Mesh2Info%node%num) ) 00395 allocate( s_rcs_node_y(self%Mesh2Info%node%num) ) 00396 00397 ! 直交座標系で表現されている格子座標データを, 地理座標系での座標データに変換する. 00398 ! 00399 00400 do rcID=1,RC_REGIONS_NUM 00401 do j=EMin, EMax 00402 do i=EMin, EMax 00403 s_rcs_AGrid(rcID,i,j,:) = orth_to_geo_pos(self%icgrid%rcs_AGrid(rcID,i,j,:)) 00404 end do 00405 end do 00406 end do 00407 00408 ! 3 次元配列を 1 次元化する. 00409 ! 00410 00411 ! 各格子の経度の情報を一次元配列に格納する. 00412 s_rcs_node_x(:) = reshape( s_rcs_AGrid(:,:,:,1), shape(s_rcs_node_x) ) 00413 ! 各格子の緯度の情報を一次元配列に格納する. 00414 s_rcs_node_y(:) = reshape( s_rcs_AGrid(:,:,:,2), shape(s_rcs_node_y) ) 00415 00416 ! 格子座標データの緯度・経度成分を, それぞれ Mesh2_node_x, Mesh2_node_y として, 00417 ! netCDF ファイルに書き込む. 00418 ! 00419 00420 call check_nf90_status( & 00421 & nf90_put_var( self%ncID, self%Mesh2Info%node_x%varID, s_rcs_node_x ) & 00422 & ) 00423 call check_nf90_status( & 00424 & nf90_put_var( self%ncID, self%Mesh2Info%node_y%varID, s_rcs_node_y ) & 00425 & ) 00426 00427 end subroutine write_GridData 00428 00429 ! 00448 subroutine write_Field2D_Data(self, varid, field_Rank1) 00449 00450 ! 宣言文 ; Declaration statements 00451 ! 00452 type(IcGrid_ncWriter), intent(in) :: self 00453 integer, intent(in) :: varid 00454 type(Field_IcGrid2D), intent(in) :: field_Rank1 00455 00456 ! 作業変数 00457 ! Work variables 00458 ! 00459 integer :: EMin, EMax 00460 real(DP), allocatable :: writed_field(:) 00461 integer :: start(2), count(2) 00462 00463 ! 実行文 ; Executable statement 00464 ! 00465 00466 ! 00467 EMin = get_EffSize_Min(self%icgrid) 00468 EMax = get_EffSize_Max(self%icgrid) 00469 00470 ! 00471 allocate(writed_field(self%Mesh2Info%node%num)) 00472 writed_field(:) = reshape( field_Rank1%val(:,EMin:EMax,EMin:EMax,1), shape(writed_field) ) 00473 00474 ! 00475 count = (/ self%Mesh2Info%node%num, 1 /) 00476 start = (/ 1, self%rec_counter /) 00477 00478 ! 00479 call check_nf90_status( & 00480 & nf90_put_var( self%ncID, varID, writed_field, start=start, count=count ) & 00481 & ) 00482 00483 00484 end subroutine write_Field2D_Data 00485 00486 ! 00497 subroutine increase_recorde_counter(self) 00498 00499 ! 宣言文 ; Declaration statements 00500 ! 00501 type(IcGrid_ncWriter), intent(inout) :: self 00502 00503 ! 実行文 ; Executable statement 00504 ! 00505 00506 self%rec_counter = self%rec_counter + 1 00507 00508 end subroutine increase_recorde_counter 00509 00510 ! 00521 subroutine close_ncFile(self) 00522 00523 ! 宣言文 ; Declaration statements 00524 ! 00525 type(IcGrid_ncWriter), intent(in) :: self 00526 00527 ! 実行文 ; Executable statement 00528 ! 00529 00530 ! netCDF ファイルを閉じる. 00531 call check_nf90_status( nf90_close(self%ncID) ) 00532 00533 end subroutine close_ncFile 00534 00535 !!!!!!!!!!!!!!!!!!!! 00536 ! 00537 ! 非公開手続き 00538 ! 00539 !!!!!!!!!!!!!!!!!!! 00540 00541 ! 00554 subroutine ncdef_dimension(self, dim_element) 00555 00556 ! 宣言文 ; Declaration statements 00557 ! 00558 type(IcGrid_ncWriter), intent(in) :: self 00559 type(Mesh_dim_element), intent(inout) :: dim_element 00560 00561 ! 実行文 ; Executable statments 00562 ! 00563 00564 call check_nf90_status( & 00565 & nf90_def_dim(self%ncID, dim_element%element_name, dim_element%num, dim_element%dimID), & 00566 message='define dimension. ' // trim(dim_element%element_name) & 00567 & ) 00568 00569 end subroutine ncdef_dimension 00570 00571 ! 00584 subroutine ncdef_mesh_coordinate(self, coordinate_element) 00585 00586 ! 宣言文 ; Declaration statements 00587 ! 00588 type(IcGrid_ncWriter), intent(in) :: self 00589 type(Mesh_coord_element), intent(inout) :: coordinate_element 00590 00591 ! 作業変数 00592 ! Work variables 00593 ! 00594 integer :: ret_status 00595 00596 ! 実行文 ; Executable statements 00597 ! 00598 00599 ! 00600 ret_status = & 00601 & nf90_def_var( & 00602 & self%ncID, & 00603 & coordinate_element%element_name, NF90_DOUBLE, & 00604 & coordinate_element%dimension_element%dimID, coordinate_element%varID & 00605 & ) 00606 00607 call check_nf90_status(ret_status) 00608 00609 end subroutine ncdef_mesh_coordinate 00610 00611 end module IcGrid_ncWriter_mod