IGMBaseLib 1.0

src/io/netcdf/IcGrid_ncWriter_mod.f90

Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables