IGMBaseLib 1.0
|
00001 00029 module Field_IcGrid2D_Manager 00030 00031 ! モジュール引用; Use statement 00032 ! 00033 00034 ! 種類型パラメータ 00035 ! Kind type parameter 00036 ! 00037 use dc_types, only: DP, & ! 倍精度実数型. Double precision. 00038 & TOKEN, & 00039 & STRING 00040 00041 ! メッセージ出力 00042 ! Messgae dump 00043 ! 00044 use dc_message, only: MessageNotify 00045 00046 ! 数学 00047 ! Mathematic 00048 ! 00049 use igmcore_math, only: PI 00050 00051 ! 正二十面体格子データの管理 00052 ! Manager of Icosahedral grid data 00053 ! 00054 use IcGrid2D_FVM_Manager, only: & 00055 & IcGrid2D_FVM, & 00056 & get_idMin, get_idMax, get_EffSize_Min, get_EffSize_Max, get_IcRadius, & 00057 & RC_REGIONS_NUM 00058 00059 ! 物理場データを管理する構造体のための基底モジュール 00060 ! Base module for some derived types to manage the physical field data 00061 ! 00062 use Physical_Field_Manager, only: & 00063 & Physical_Field, & 00064 & Physical_Field_Init, & 00065 & get_name_ => get_field_name, & 00066 & get_long_name_ => get_long_field_name, & 00067 & get_dimension_ => get_field_rank, & 00068 & get_units_ => get_field_units, & 00069 & set_name_ => set_field_name, & 00070 & set_long_name_ => set_long_field_name, & 00071 & set_units_ => set_field_units 00072 00073 ! 宣言文 ; Declaration statement 00074 ! 00075 implicit none 00076 private 00077 00078 ! 00093 type, public :: Field_IcGrid2D 00094 00109 real(DP), pointer :: val(:,:,:,:) => null() 00110 ! f2003: real(DP), allocatable :: val(:,:,:,:) 00111 00112 ! 非公開メンバ変数 00113 ! Private memeber variables 00114 ! 00115 00118 type(Physical_Field) :: base 00119 ! f2003: type(Physical_Field), private :: base 00120 00123 type(IcGrid2D_FVM), pointer :: icgrid 00124 ! f2003: type(IcGrid2D_FVM), pointer, private :: icgrid 00125 00126 end type Field_IcGrid2D 00127 00128 ! interface 文 ; interface statements 00129 ! 00130 interface Field_IcGrid2D_Init 00131 module procedure init_Field_IcGrid2D1 00132 module procedure init_Field_IcGrid2D2 00133 end interface Field_IcGrid2D_Init 00134 00135 ! 公開手続き 00136 ! Public procedures 00137 ! 00138 00139 public :: Field_IcGrid2D_Init, Field_IcGrid2D_Final 00140 public :: paste_field_margin, global_mean 00141 public :: get_icgrid, get_Physical_Field 00142 00143 public :: get_field2D_name, get_long_field2D_name, get_field2D_rank, get_field2D_units 00144 public :: set_field2D_name, set_long_field2D_name, set_field2D_units 00145 00146 contains 00147 00148 ! 00168 subroutine init_Field_IcGrid2D0( & 00169 & self, & ! (inout) 00170 & icgrid, name, field_rank, & ! (in) 00171 & long_name, units & ! (in) 00172 & ) 00173 00174 ! 宣言文 ; Declaration statement 00175 ! 00176 type(Field_IcGrid2D), intent(inout) :: self 00177 type(IcGrid2D_FVM), pointer :: icgrid 00178 character(*), intent(in) :: name 00179 integer, intent(in) :: field_rank 00180 character(*), intent(in) :: long_name 00181 character(*), intent(in) :: units 00182 00183 ! 作業変数 00184 ! Work variables 00185 ! 00186 integer :: idMin, idMax 00187 00188 ! 実行文 ; Executable statement 00189 ! 00190 ! write(*,*) 'Field_IcGrid2D initialize, name=', trim(name) 00191 00192 self%icgrid => icgrid 00193 00194 idMin = get_IdMin(self%icgrid) 00195 idMax = get_IdMax(self%icgrid) 00196 00197 ! 物理場データを格納する配列のメモリを確保する. 00198 allocate(self%val(RC_REGIONS_NUM, idMin:idMax, idMin:idMax, 1:field_rank)) 00199 00200 ! 基底構造体の初期化関数を呼び出す. 00201 call Physical_Field_Init(self%base, name, field_rank, long_name, units) 00202 00203 end subroutine init_Field_IcGrid2D0 00204 00205 ! 00225 subroutine init_Field_IcGrid2D1( & 00226 & self, & ! (inout) 00227 & icgrid, name, rank, long_name, units & ! (in) 00228 & ) 00229 00230 ! 宣言文 ; Declaration statement 00231 ! 00232 type(Field_IcGrid2D), intent(inout) :: self 00233 type(IcGrid2D_FVM), intent(in), target :: icgrid 00234 character(*), intent(in) :: name 00235 integer, intent(in) :: rank 00236 character(*), intent(in) :: long_name 00237 character(*), intent(in) :: units 00238 00239 ! 作業変数 00240 ! Work variables 00241 ! 00242 integer :: idMin, idMax 00243 type(IcGrid2D_FVM), pointer :: icgrid_ptr 00244 00245 ! 実行文 ; Executable statement 00246 ! 00247 00248 ! write(*,*) 'Field_IcGrid2D initialize, name=', trim(name) 00249 00250 ! 00251 icgrid_ptr => icgrid 00252 call init_Field_IcGrid2D0(self, icgrid_ptr, name, rank, long_name, units) 00253 00254 end subroutine init_Field_IcGrid2D1 00255 00256 ! 00273 subroutine init_Field_IcGrid2D2( & 00274 & self, & ! (inout) 00275 & icgrid, name, rank & ! (in) 00276 & ) 00277 00278 ! 宣言文 ; Declaration statement 00279 ! 00280 type(Field_IcGrid2D), intent(inout) :: self 00281 type(IcGrid2D_FVM), intent(in), target :: icgrid 00282 character(*), intent(in) :: name 00283 integer, intent(in) :: rank 00284 00285 ! 作業変数 00286 ! Work variables 00287 ! 00288 00289 ! 実行文 ; Executable statement 00290 ! 00291 00292 call init_Field_IcGrid2D1(self, icgrid, name, rank, '', '') 00293 00294 end subroutine init_Field_IcGrid2D2 00295 00296 ! 00307 subroutine Field_IcGrid2D_Final( & 00308 & self & ! (inout) 00309 & ) 00310 00311 ! 宣言文 ; Declaration statement 00312 ! 00313 type(Field_IcGrid2D), intent(inout) :: self 00314 00315 ! 実行文 ; Executable statement 00316 ! 00317 00318 ! write(*,*) 'Field_IcGrid2D finalize, name=', trim(get_name(self)) 00319 00320 ! 物理場データを保持している配列のメモリを解放する. 00321 deallocate(self%val) 00322 00323 end subroutine Field_IcGrid2D_Final 00324 00325 ! 00338 function get_Physical_Field( & 00339 & self & ! (inout) 00340 & ) result(val) 00341 00342 ! 宣言文 ; Declaration statements 00343 ! 00344 type(Field_IcGrid2D), intent(inout), target :: self 00345 type(Physical_Field), pointer :: val 00346 00347 ! 実行文 ; Executable statements 00348 ! 00349 val => self%base 00350 00351 end function get_Physical_Field 00352 00353 ! 00366 function get_icgrid( & 00367 & self & ! (inout) 00368 & ) result(icgrid) 00369 00370 ! 宣言文 ; Declaration statement 00371 ! 00372 type(Field_IcGrid2D), intent(in) :: self ! 00373 type(IcGrid2D_FVM), pointer :: icgrid 00374 00375 ! 実行文 ; Executable statement 00376 ! 00377 00378 icgrid => self%icgrid 00379 00380 end function get_icgrid 00381 00382 ! 00393 subroutine paste_field_margin( & 00394 & self & ! (inout) 00395 & ) 00396 00397 ! 宣言文 ; Declaration statements 00398 ! 00399 type(Field_IcGrid2D), intent(inout) :: self ! 00400 00401 ! 作業変数 00402 ! Work variables 00403 ! 00404 integer :: idlist1(7) = (/ 5, 1, 2, 3, 4, 5, 1 /) 00405 integer :: idlist2(7) = (/ 10, 6, 7, 8, 9, 10, 6 /) 00406 integer :: EMin, EMax, marginw, idMin 00407 integer i, k 00408 00409 ! 実行文 ; Executable statements 00410 ! 00411 00412 EMin = get_EffSize_Min(self%icgrid) 00413 EMax = get_EffSize_Max(self%icgrid) 00414 00415 ! ノリシロの幅を計算する. 00416 idMin = get_IdMin(self%icgrid) 00417 marginw = EMin - idMin 00418 00419 do i=1, RC_REGIONS_NUM/2 00420 do k=1, marginw 00421 ! 北半球側の矩形領域ののりしろに値をコピーする. 00422 self%val(i, EMin:EMax, EMin-k, :) = self%val(idlist1(i), EMin+k, EMin:EMax, :) 00423 self%val(i, EMax+k, EMin:EMax, :) = self%val(idlist2(i), EMin+k, EMin:EMax, :) 00424 self%val(i, EMin:EMax, EMax+k, :) = self%val(idlist2(i+1), EMin:EMax, EMin+k, :) 00425 self%val(i, EMin-k, EMin:EMax, :) = self%val(idlist1(i+2), EMin:EMax, EMin+k, :) 00426 00427 ! 南半球側の矩形領域ののりしろに値をコピーする. 00428 self%val(i+5, EMin:EMax, EMin-k, :) = self%val(idlist1(i+1), EMin:EMax, EMax-k, :) 00429 self%val(i+5, EMax+k, EMin:EMax, :) = self%val(idlist2(i), EMin:EMax, EMax-k, :) 00430 self%val(i+5, EMin:EMax, EMax+k, :) = self%val(idlist2(i+2), EMax-k, EMin:EMax, :) 00431 self%val(i+5, EMin-k, EMin:EMax, :) = self%val(idlist1(i+2), EMax-k, EMin:EMax, :) 00432 end do 00433 end do 00434 00435 end subroutine paste_field_margin 00436 00437 ! 00450 function global_mean( & 00451 & self & ! (inout) 00452 & ) result(val) 00453 00454 ! 宣言文 ; Declaration statement 00455 ! 00456 type(Field_IcGrid2D), intent(inout) :: self ! 00457 real(DP) val 00458 00459 ! 作業変数 00460 ! Work variables 00461 ! 00462 integer :: rcID, i, j 00463 integer :: EMin, EMax 00464 type(IcGrid2D_FVM), pointer :: icgrid 00465 00466 ! 実行文 ; Executable statement 00467 ! 00468 00469 ! 物理場のランクが 1 次元(スカラー場)であることを確認する. 00470 if( get_field2D_rank(self) /= 1 ) then 00471 call MessageNotify( 'E', 'IGMBaseLib IO::Field_IcGrid2D::global_mean', & 00472 & "The rank of Field_IcGrid2D(=%d) is invalid.", i=(/ get_field2D_rank(self) /) ) 00473 stop 00474 return 00475 end if 00476 00477 EMin = get_EffSize_Min(self%icgrid) 00478 EMax = get_EffSize_Max(self%icgrid) 00479 icgrid => self%icgrid 00480 00481 ! まず指定されたスカラー場の, 全球積分値を求める. 00482 val = self%val(1,EMin,EMin, 1) * icgrid%rcs_CVArea(1,EMin,EMin) & 00483 + self%val(10,EMax,EMax, 1) * icgrid%rcs_CVArea(10,EMax,EMax) 00484 00485 do rcID=1, RC_REGIONS_NUM 00486 do j=EMin, EMax-1 00487 do i=EMin+1, EMax 00488 val = val + self%val(rcID,i,j, 1) * icgrid%rcs_CVArea(rcID,i,j) 00489 end do 00490 end do 00491 end do 00492 00493 ! 球の面積で規格化する. 00494 val = val / ( 4.0d0 * PI * get_IcRadius(icgrid)**2 ) 00495 00496 end function global_mean 00497 00498 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00499 ! 00500 ! Physical_Field_mod の手続きをオーバライド 00501 ! 00502 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00503 00504 00505 ! 00518 function get_long_field2D_name(self) result(val) 00519 00520 ! 宣言文 ; Declaration statement 00521 ! 00522 type(Field_IcGrid2D), intent(in) :: self 00523 character(STRING) val 00524 00525 ! 実行文 ; Executable statement 00526 ! 00527 00528 val = get_long_name_(self%base) 00529 00530 end function get_long_field2D_name 00531 00532 ! 00545 subroutine set_long_field2D_name(self, long_name) 00546 ! 宣言文 ; Declaration statement 00547 ! 00548 type(Field_IcGrid2D), intent(inout) :: self 00549 character(*), intent(in) :: long_name 00550 00551 ! 実行文 ; Executable statement 00552 ! 00553 00554 call set_long_name_(self%base, long_name) 00555 00556 end subroutine set_long_field2D_name 00557 00558 ! 00571 function get_field2D_units(self) result(val) 00572 ! 宣言文 ; Declaration statement 00573 ! 00574 type(Field_IcGrid2D), intent(in) :: self 00575 character(TOKEN) val 00576 00577 ! 実行文 ; Executable statement 00578 ! 00579 00580 val = get_units_(self%base) 00581 00582 end function get_field2D_units 00583 00584 ! 00597 subroutine set_field2D_units(self, units) 00598 ! 宣言文 ; Declaration statement 00599 ! 00600 type(Field_IcGrid2D), intent(inout) :: self 00601 character(*), intent(in) :: units 00602 00603 ! 実行文 ; Executable statement 00604 ! 00605 00606 call set_units_(self%base, units) 00607 00608 end subroutine set_field2D_units 00609 00610 ! 00623 function get_field2D_rank(self) result(val) 00624 ! 宣言文 ; Declaration statement 00625 ! 00626 type(Field_IcGrid2D), intent(in) :: self 00627 integer val 00628 00629 ! 実行文 ; Executable statement 00630 ! 00631 00632 val = get_dimension_(self%base) 00633 00634 end function get_field2D_rank 00635 00636 00637 ! 00650 function get_field2D_name( & 00651 & self & 00652 & ) result(name) 00653 00654 ! 宣言文 ; Declaration statement 00655 ! 00656 type(Field_IcGrid2D), intent(in) :: self ! 00657 character(TOKEN) name 00658 00659 ! 実行文 ; Executable statement 00660 ! 00661 00662 name = get_name_(self%base) 00663 00664 end function get_field2D_name 00665 00666 ! 00679 subroutine set_field2D_name( & 00680 & self, name ) 00681 00682 ! 宣言文 ; Declaration statement 00683 ! 00684 type(Field_IcGrid2D), intent(inout) :: self 00685 character(*), intent(in) :: name 00686 00687 ! 実行文 ; Executable statement 00688 ! 00689 00690 call set_name_(self%base, name) 00691 00692 end subroutine set_field2D_name 00693 00694 end module Field_IcGrid2D_Manager