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