IGMBaseLib 1.0

src/util/field/Field_Pattern_Builder.f90

Go to the documentation of this file.
00001 
00024 module Field_Pattern_Builder
00025 
00026   ! モジュール引用 ; Use statements
00027   !
00028 
00029   ! 種類型パラメータ
00030   ! Kind type parameter 
00031   !
00032   use dc_types, only: DP  ! 倍精度実数型. Double precision. 
00033   
00034   ! 数学
00035   ! Mathematic
00036   !
00037   use igmcore_math, only: PI
00038 
00039   ! 線形代数
00040   ! Linear algebra
00041   !
00042   use igmcore_linear_algebra, only: &
00043     & cross, rotateY
00044 
00045   ! 座標変換
00046   ! Coordinate conversion
00047   !
00048   use igmcore_coordinate_conversion, only: &
00049     & orth_to_geo_pos, geo_to_orth_pos
00050 
00051   ! 球面三角法
00052   ! Spherical trigometry
00053   !
00054   use igmcore_spherical_trigonometry, only: &
00055     & geodesic_arc_length
00056   
00057   ! 正二十面体格子の管理
00058   ! Manager of icosahedral grid
00059   !
00060   use IcGrid2D_FVM_Manager, only: &
00061     & IcGrid2D_FVM, &
00062     & check_pole, &
00063     & get_EffSize_Min, get_EffSize_Max, get_IcRadius, &
00064     & RC_REGIONS_NUM, NORTH_POLE_FLAG, SOUTH_POLE_FLAG, NOT_POLE_FLAG
00065 
00066   ! 正二十面体格子上の物理場データの管理
00067   ! Manager of a physical field data on icosahedral grid
00068   !
00069   use Field_IcGrid2D_Manager, only: &
00070     & Field_IcGrid2D, &
00071     & get_icgrid
00072 
00073   ! 宣言文 ; Declaration statement
00074   ! 
00075   implicit none
00076   private
00077 
00078   ! 公開手続き
00079   ! Public procedures
00080   !
00081   public :: create_solid_rotation_field, create_planetaryVorticity_field
00082   public :: create_cosine_bell_field
00083 
00084 contains
00085 
00100 subroutine create_solid_rotation_field(field, angular_speed, alpha)
00101 
00102   ! 宣言文 ; Declaration statement
00103   !
00104   type(Field_IcGrid2D), intent(inout) :: field
00105   real(DP), intent(in) :: angular_speed
00106   real(DP), intent(in) :: alpha
00107 
00108   ! 作業変数
00109   ! Work variables
00110   !
00111   type(IcGrid2D_FVM), pointer :: icgrid
00112   integer :: rcID, i,j
00113   integer :: EMin, EMax
00114   real(DP) :: Omega_vec(3)
00115 
00116   ! 実行文 ; Executable statement
00117   !
00118 
00119   !
00120   icgrid => get_icgrid(field)
00121   EMin = get_EffSize_Min(icgrid)
00122   EMax = get_EffSize_Max(icgrid)
00123   Omega_vec(:) = (/ sin(alpha), 0.0d0, cos(alpha) /)
00124 
00125   do rcID=1, RC_REGIONS_NUM
00126     do j=EMin, EMax
00127       do i=EMin, EMax
00128 
00129         !
00130         field%val(rcID,i,j,:) = &
00131           & angular_speed * cross( Omega_vec(:), icgrid%rcs_AGrid(rcID,i,j,:))
00132         end do
00133     end do
00134   end do
00135 
00136 end subroutine create_solid_rotation_field
00137 
00152 subroutine create_planetaryVorticity_field(field, angular_speed, alpha)
00153 
00154   ! 宣言文 ; Declaration statement
00155   !
00156   type(Field_IcGrid2D), intent(inout) :: field
00157   real(DP), intent(in) :: angular_speed
00158   real(DP), intent(in) :: alpha
00159 
00160   ! 作業変数
00161   ! Work variables
00162   !
00163   type(IcGrid2D_FVM), pointer :: icgrid
00164   integer :: rcID, i,j
00165   integer :: EMin, EMax
00166   real(DP) :: s_pos(3)
00167 
00168   ! 実行文 ; Executable statement
00169   !
00170 
00171   !
00172   icgrid => get_icgrid(field)
00173   EMin = get_EffSize_Min(icgrid)
00174   EMax = get_EffSize_Max(icgrid)
00175 
00176   do rcID=1, RC_REGIONS_NUM
00177     do j=EMin, EMax
00178       do i=EMin, EMax
00179          s_pos(:) = orth_to_geo_pos(icgrid%rcs_Agrid(rcID,i,j,:))
00180 
00181         if ( check_pole(icgrid, rcID,i,j) == NOT_POLE_FLAG ) then
00182           field%val(rcID,i,j,:) = 2.0d0 * angular_speed * ( &
00183           &    cos(s_pos(1)) * cos(s_pos(2)) * sin(alpha) + sin(s_pos(2)) * cos(alpha) &
00184             &   )
00185         else
00186           field%val(rcID,i,j,:) = 2.0d0 * angular_speed * sin(s_pos(2)) * cos(alpha)
00187         end if
00188       end do
00189     end do
00190   end do
00191 
00192 end subroutine create_planetaryVorticity_field
00193 
00194 !
00213 subroutine create_cosine_bell_field(field, lambda_c, theta_c, cbR, h0)
00214 
00215   ! 宣言文 ; Declaration statement
00216   !
00217   type(Field_IcGrid2D), intent(inout) :: field
00218   real(DP), intent(in) :: lambda_c
00219   real(DP), intent(in) :: theta_c
00220   real(DP), intent(in) :: cbR
00221   real(DP), intent(in) :: h0
00222   
00223   ! 作業変数
00224   ! Work variables
00225   !
00226   type(IcGrid2D_FVM), pointer :: icgrid
00227   real(DP) :: ic_radius
00228   real(DP) :: orth_c(3)
00229 
00232   real(DP) :: r
00233 
00234   integer :: rcID, i,j
00235   integer :: EMin, EMax
00236 
00237   ! 実行文 ; Executable statement
00238   !
00239   
00240   !
00241   icgrid => get_icgrid(field)
00242   ic_radius = get_IcRadius(icgrid)
00243   EMin = get_EffSize_Min(icgrid)
00244   EMax = get_EffSize_Max(icgrid)
00245   
00246   orth_c = geo_to_orth_pos( (/lambda_c, theta_c, ic_radius /) )
00247  
00248   do rcID=1, RC_REGIONS_NUM
00249     do j=EMin, EMax
00250       do i=EMin, EMax
00251         r = geodesic_arc_length(ic_radius, orth_c, icgrid%rcs_AGrid(rcID,i,j,:))
00252         
00253         if( r < cbR ) then
00254           field%val(rcID,i,j, :) = 0.5d0 * h0 * ( 1.0d0 + cos(PI*r/cbR) )
00255         else
00256           field%val(rcID,i,j, :) = 0.0d0
00257         end if
00258 
00259       end do
00260     end do
00261   end do
00262 
00263 end subroutine create_cosine_bell_field
00264 
00265 end module Field_Pattern_Builder
 All Classes Namespaces Files Functions Variables