Changeset 213 for codes/icosagcm/trunk
- Timestamp:
- 07/15/14 18:15:39 (10 years ago)
- Location:
- codes/icosagcm/trunk/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
codes/icosagcm/trunk/src/physics.f90
r196 r213 7 7 INTEGER, PARAMETER :: phys_none=0, phys_HS94=1, phys_DCMIP=2 8 8 9 INTEGER :: nb_extra_physics_2D, nb_extra_physics_3D,phys_type9 INTEGER :: phys_type 10 10 TYPE(t_field),POINTER :: f_extra_physics_2D(:), f_extra_physics_3D(:) 11 TYPE(t_field),POINTER :: f_dulon(:), f_dulat(:) 11 12 12 13 CHARACTER(LEN=255) :: physics_type="automatic" … … 14 15 15 16 PUBLIC :: physics, init_physics 17 16 18 CONTAINS 17 19 … … 21 23 USE icosa 22 24 USE physics_interface_mod 23 USE physics_dcmip_mod, ONLY : init_physics_dcmip=>init_physics 24 IMPLICIT NONE 25 25 USE physics_dcmip_mod, ONLY : & 26 init_physics_dcmip=>init_physics, init_physics_dcmip_new=>init_physics_new 27 IMPLICIT NONE 28 29 CALL allocate_field(f_dulon,field_t,type_real,llm, name='dulon') 30 CALL allocate_field(f_dulat,field_t,type_real,llm, name='dulat') 31 CALL init_pack_before ! Compute physics_inout%ngrid and offsets used by pack/unpack 32 26 33 physics_type='automatic' 27 34 CALL getin("physics",physics_type) … … 40 47 41 48 CASE ('dcmip') 42 CALL init_physics_dcmip 43 nb_extra_physics_2D=1 ! precl 44 nb_extra_physics_3D=0 49 CALL init_physics_dcmip_new 50 ! CALL init_physics_dcmip 45 51 phys_type = phys_DCMIP 46 52 CASE DEFAULT … … 55 61 PRINT *, 'nb_extra_physics_3D = ', nb_extra_physics_3D 56 62 END IF 57 IF(nb_extra_physics_2D>0) CALL allocate_field(f_extra_physics_2D,field_t,type_real,nb_extra_physics_2D) 58 IF(nb_extra_physics_3D>0) CALL allocate_field(f_extra_physics_3D,field_t,type_real,llm,nb_extra_physics_3D) 59 63 64 IF(.FALSE.) THEN ! draft interface 65 IF(nb_extra_physics_2D>0) CALL allocate_field(f_extra_physics_2D,field_t,type_real,nb_extra_physics_2D) 66 IF(nb_extra_physics_3D>0) CALL allocate_field(f_extra_physics_3D,field_t,type_real,llm,nb_extra_physics_3D) 67 ELSE 68 CALL init_pack_after ! Defines Ai, lon, lat in physics_inout 69 END IF 60 70 END SUBROUTINE init_physics 61 71 … … 63 73 USE icosa 64 74 USE physics_interface_mod 65 ! USE etat0_mod75 USE physics_dcmip_mod, ONLY : write_physics_dcmip => write_physics 66 76 USE etat0_heldsz_mod 67 77 IMPLICIT NONE … … 81 91 LOGICAL:: firstcall,lastcall 82 92 INTEGER :: ind 83 TYPE(physics_inout) :: args 93 TYPE(t_physics_inout) :: args 94 95 IF(MOD(it+1,itau_physics)==0) THEN 96 97 SELECT CASE(phys_type) 98 CASE (phys_none) 99 ! No physics, do nothing 100 CASE(phys_HS94) 101 CALL held_suarez(f_ps,f_theta_rhodz,f_ue) 102 CASE DEFAULT 103 IF(.FALSE.) THEN ! draft interface 104 args%dt_phys = dt*itau_physics 105 DO ind=1,ndomain 106 IF (.NOT. assigned_domain(ind)) CYCLE 107 CALL swap_dimensions(ind) 108 CALL swap_geometry(ind) 109 110 phis=f_phis(ind) 111 ps=f_ps(ind) 112 theta_rhodz=f_theta_rhodz(ind) 113 ue=f_ue(ind) 114 q=f_q(ind) 115 116 IF(nb_extra_physics_2D>0) args%extra_2D=f_extra_physics_2D(ind) 117 IF(nb_extra_physics_3D>0) args%extra_3D=f_extra_physics_3D(ind) 118 CALL physics_column(args, phis, ps, theta_rhodz, ue, q) 119 ENDDO 120 121 IF (mod(it,itau_out)==0 ) THEN 122 IF(nb_extra_physics_2D>0) CALL writefield("extra_physics_2D",f_extra_physics_2D) 123 IF(nb_extra_physics_3D>0) CALL writefield("extra_physics_3D",f_extra_physics_3D) 124 ENDIF 125 ELSE ! new interface 126 physics_inout%dt_phys = dt*itau_physics 127 CALL physics_column_new(it, f_phis, f_ps, f_theta_rhodz, f_ue, f_q) 128 END IF 129 END SELECT 130 131 CALL transfert_request(f_theta_rhodz,req_i0) 132 CALL transfert_request(f_ue,req_e0_vect) 133 CALL transfert_request(f_q,req_i0) 134 END IF 135 136 IF (mod(it,itau_out)==0 ) THEN 137 SELECT CASE(phys_type) 138 CASE (phys_DCMIP) 139 CALL write_physics_dcmip 140 END SELECT 141 END IF 142 143 END SUBROUTINE physics 144 145 !--------------------------------- New interface -------------------------------------- 146 147 SUBROUTINE physics_column_new(it, f_phis, f_ps, f_theta_rhodz, f_ue, f_q) 148 USE icosa 149 USE physics_interface_mod 150 USE physics_dcmip_mod, ONLY : full_physics_dcmip => full_physics 151 IMPLICIT NONE 152 TYPE(t_field),POINTER :: f_phis(:) 153 TYPE(t_field),POINTER :: f_ps(:) 154 TYPE(t_field),POINTER :: f_theta_rhodz(:) 155 TYPE(t_field),POINTER :: f_ue(:) 156 TYPE(t_field),POINTER :: f_q(:) 157 REAL(rstd),POINTER :: phis(:) 158 REAL(rstd),POINTER :: ps(:) 159 REAL(rstd),POINTER :: theta_rhodz(:,:) 160 REAL(rstd),POINTER :: ue(:,:) 161 REAL(rstd),POINTER :: dulon(:,:) 162 REAL(rstd),POINTER :: dulat(:,:) 163 REAL(rstd),POINTER :: q(:,:,:) 164 INTEGER :: it, ind 165 166 DO ind=1,ndomain 167 IF (.NOT. assigned_domain(ind)) CYCLE 168 CALL swap_dimensions(ind) 169 CALL swap_geometry(ind) 170 phis=f_phis(ind) 171 ps=f_ps(ind) 172 theta_rhodz=f_theta_rhodz(ind) 173 ue=f_ue(ind) 174 q=f_q(ind) 175 CALL pack_physics(pack_info(ind), phis, ps, theta_rhodz, ue, q) 176 END DO 84 177 85 178 SELECT CASE(phys_type) 86 CASE (phys_none) 87 ! No physics, do nothing 88 CASE(phys_HS94) 89 CALL held_suarez(f_ps,f_theta_rhodz,f_ue) 90 CASE DEFAULT 91 CALL transfert_request(f_ps,req_i1) 92 CALL transfert_request(f_theta_rhodz,req_i1) 93 CALL transfert_request(f_ue,req_e1_vect) 94 CALL transfert_request(f_q,req_i1) 95 96 args%dt_phys = dt 97 DO ind=1,ndomain 98 IF (.NOT. assigned_domain(ind)) CYCLE 99 CALL swap_dimensions(ind) 100 CALL swap_geometry(ind) 101 102 phis=f_phis(ind) 103 ps=f_ps(ind) 104 theta_rhodz=f_theta_rhodz(ind) 105 ue=f_ue(ind) 106 q=f_q(ind) 107 108 IF(nb_extra_physics_2D>0) args%extra_2D=f_extra_physics_2D(ind) 109 IF(nb_extra_physics_3D>0) args%extra_3D=f_extra_physics_3D(ind) 110 CALL physics_column(args, phis, ps, theta_rhodz, ue, q) 111 ENDDO 112 113 IF (mod(it,itau_out)==0 ) THEN 114 IF(nb_extra_physics_2D>0) CALL writefield("extra_physics_2D",f_extra_physics_2D) 115 IF(nb_extra_physics_3D>0) CALL writefield("extra_physics_3D",f_extra_physics_3D) 116 ENDIF 179 CASE (phys_DCMIP) 180 CALL full_physics_dcmip 117 181 END SELECT 118 182 119 END SUBROUTINE physics 120 121 SUBROUTINE physics_column(args, phis, ps, theta_rhodz, ue, q) 183 DO ind=1,ndomain 184 IF (.NOT. assigned_domain(ind)) CYCLE 185 CALL swap_dimensions(ind) 186 CALL swap_geometry(ind) 187 ps=f_ps(ind) 188 theta_rhodz=f_theta_rhodz(ind) 189 q=f_q(ind) 190 dulon=f_dulon(ind) 191 dulat=f_dulat(ind) 192 CALL unpack_physics(pack_info(ind), ps, theta_rhodz, q, dulon, dulat) 193 END DO 194 195 ! Transfer dulon, dulat 196 CALL transfert_request(f_dulon,req_i0) 197 CALL transfert_request(f_dulat,req_i0) 198 199 DO ind=1,ndomain 200 IF (.NOT. assigned_domain(ind)) CYCLE 201 CALL swap_dimensions(ind) 202 CALL swap_geometry(ind) 203 ue=f_ue(ind) 204 dulon=f_dulon(ind) 205 dulat=f_dulat(ind) 206 CALL compute_update_velocity(dulon, dulat, ue) 207 END DO 208 209 END SUBROUTINE physics_column_new 210 211 SUBROUTINE pack_physics(info, phis, ps, theta_rhodz, ue, q) 122 212 USE icosa 123 213 USE wind_mod … … 125 215 USE theta2theta_rhodz_mod 126 216 USE physics_interface_mod 217 IMPLICIT NONE 218 TYPE(t_pack_info) :: info 219 REAL(rstd) :: phis(iim*jjm) 220 REAL(rstd) :: ps(iim*jjm) 221 REAL(rstd) :: theta_rhodz(iim*jjm,llm) 222 REAL(rstd) :: ue(3*iim*jjm,llm) 223 REAL(rstd) :: q(iim*jjm,llm,nqtot) 224 225 REAL(rstd) :: p(iim*jjm,llm+1) 226 REAL(rstd) :: Temp(iim*jjm,llm) 227 REAL(rstd) :: uc(iim*jjm,3,llm) 228 REAL(rstd) :: ulon(iim*jjm,llm) 229 REAL(rstd) :: ulat(iim*jjm,llm) 230 231 CALL compute_pression(ps,p,0) 232 CALL compute_theta_rhodz2temperature(ps,theta_rhodz,Temp,0) 233 CALL compute_wind_centered(ue,uc) 234 CALL compute_wind_centered_lonlat_compound(uc, ulon, ulat) 235 236 CALL pack_domain(info, phis, physics_inout%phis) 237 CALL pack_domain(info, p, physics_inout%p) 238 CALL pack_domain(info, Temp, physics_inout%Temp) 239 CALL pack_domain(info, ulon, physics_inout%ulon) 240 CALL pack_domain(info, ulat, physics_inout%ulat) 241 CALL pack_domain(info, q, physics_inout%q) 242 END SUBROUTINE pack_physics 243 244 SUBROUTINE unpack_physics(info, ps,theta_rhodz, q, dulon, dulat) 245 USE icosa 246 USE physics_interface_mod 247 USE theta2theta_rhodz_mod 248 IMPLICIT NONE 249 TYPE(t_pack_info) :: info 250 REAL(rstd) :: ps(iim*jjm) 251 REAL(rstd) :: theta_rhodz(iim*jjm,llm) 252 REAL(rstd) :: Temp(iim*jjm,llm) 253 REAL(rstd) :: q(iim*jjm,llm,nqtot) 254 REAL(rstd) :: dulon(iim*jjm,llm) 255 REAL(rstd) :: dulat(iim*jjm,llm) 256 257 REAL(rstd) :: dq(iim*jjm,llm,nqtot) 258 REAL(rstd) :: dTemp(iim*jjm,llm) 259 CALL unpack_domain(info, dulon, physics_inout%dulon) 260 CALL unpack_domain(info, dulat, physics_inout%dulat) 261 CALL unpack_domain(info, dq, physics_inout%dq) 262 CALL unpack_domain(info, Temp, physics_inout%Temp) 263 CALL unpack_domain(info, dTemp, physics_inout%dTemp) 264 q = q + physics_inout%dt_phys * dq 265 Temp = Temp + physics_inout%dt_phys * dTemp 266 CALL compute_temperature2theta_rhodz(ps,Temp,theta_rhodz,0) 267 END SUBROUTINE unpack_physics 268 269 SUBROUTINE compute_update_velocity(dulon, dulat, ue) 270 USE icosa 271 USE physics_interface_mod 272 USE wind_mod 273 IMPLICIT NONE 274 REAL(rstd) :: dulon(iim*jjm,llm) 275 REAL(rstd) :: dulat(iim*jjm,llm) 276 REAL(rstd) :: ue(3*iim*jjm,llm) 277 REAL(rstd) :: duc(iim*jjm,3,llm) 278 REAL(rstd) :: dt2, due 279 INTEGER :: i,j,ij,l 280 ! Reconstruct wind tendencies at edges and add to normal wind 281 CALL compute_wind_centered_from_lonlat_compound(dulon,dulat,duc) 282 dt2=.5*physics_inout%dt_phys 283 DO l=1,llm 284 DO j=jj_begin,jj_end 285 DO i=ii_begin,ii_end 286 ij=(j-1)*iim+i 287 due = sum( (duc(ij,:,l) + duc(ij+t_right,:,l))*ep_e(ij+u_right,:) ) 288 ue(ij+u_right,l) = ue(ij+u_right,l) + dt2*due 289 290 due = sum( (duc(ij,:,l) + duc(ij+t_lup,:,l))*ep_e(ij+u_lup,:) ) 291 ue(ij+u_lup,l)=ue(ij+u_lup,l) + dt2*due 292 293 due = sum( (duc(ij,:,l) + duc(ij+t_ldown,:,l))*ep_e(ij+u_ldown,:) ) 294 ue(ij+u_ldown,l)=ue(ij+u_ldown,l) + dt2*due 295 ENDDO 296 ENDDO 297 ENDDO 298 END SUBROUTINE compute_update_velocity 299 300 !--------------------------------- Draft interface -------------------------------------- 301 302 SUBROUTINE physics_column(args, phis, ps, theta_rhodz, ue, q) 303 USE icosa 304 USE wind_mod 305 USE pression_mod 306 USE theta2theta_rhodz_mod 307 USE physics_interface_mod 127 308 USE physics_dcmip_mod 128 309 IMPLICIT NONE 129 TYPE( physics_inout) :: args310 TYPE(t_physics_inout) :: args 130 311 REAL(rstd) :: phis(iim*jjm) 131 312 REAL(rstd) :: ps(iim*jjm) … … 190 371 DO i=ii_begin,ii_end 191 372 ij=(j-1)*iim+i 192 due = sum( (uc(ij,:,l) + uc(ij+t_right,:,l))*ep_e(ij+u_right,:) )373 due = sum( (uc(ij,:,l) + uc(ij+t_right,:,l))*ep_e(ij+u_right,:) ) 193 374 ue(ij+u_right,l) = ue(ij+u_right,l) + dt2*due 194 375 -
codes/icosagcm/trunk/src/physics_dcmip.f90
r196 r213 7 7 8 8 TYPE(t_field),POINTER :: f_out_i(:) 9 TYPE(t_field),POINTER :: f_precl(:)10 9 REAL(rstd),POINTER :: out_i(:,:) 11 10 12 PUBLIC :: compute_phys_wrap, init_physics 11 TYPE(t_field),POINTER :: f_precl(:) 12 REAL(rstd),ALLOCATABLE :: precl_packed(:) 13 14 PUBLIC :: compute_phys_wrap, init_physics, & 15 init_physics_new, full_physics, write_physics 13 16 14 17 CONTAINS 15 18 19 !-------------------------- New interface ---------------------- 20 21 SUBROUTINE init_physics_new 22 USE physics_interface_mod 23 IMPLICIT NONE 24 INTEGER :: ngrid 25 testcase=1 ! OK for 4.2 (moist baroclinic instability) 26 CALL getin("dcmip_physics",testcase) 27 ngrid = physics_inout%ngrid 28 ! Input 29 ALLOCATE(physics_inout%Ai(ngrid)) 30 ALLOCATE(physics_inout%lon(ngrid)) 31 ALLOCATE(physics_inout%lat(ngrid)) 32 ALLOCATE(physics_inout%phis(ngrid)) 33 ALLOCATE(physics_inout%p(ngrid,llm+1)) 34 ALLOCATE(physics_inout%Temp(ngrid,llm)) 35 ALLOCATE(physics_inout%ulon(ngrid,llm)) 36 ALLOCATE(physics_inout%ulat(ngrid,llm)) 37 ALLOCATE(physics_inout%q(ngrid,llm,nqtot)) 38 ! Output (tendencies) 39 ALLOCATE(physics_inout%dTemp(ngrid,llm)) 40 ALLOCATE(physics_inout%dulon(ngrid,llm)) 41 ALLOCATE(physics_inout%dulat(ngrid,llm)) 42 ALLOCATE(physics_inout%dq(ngrid,llm,nqtot)) 43 ! Physics-specific data 44 ALLOCATE(precl_packed(ngrid)) 45 CALL allocate_field(f_precl, field_t,type_real) 46 47 PRINT *, 'init_physics_new', SIZE(physics_inout%Ai) 48 END SUBROUTINE init_physics_new 49 50 SUBROUTINE full_physics 51 USE physics_interface_mod 52 CALL compute_physics(physics_inout%ngrid, physics_inout%dt_phys, & 53 physics_inout%lat, physics_inout%p, physics_inout%Temp, & 54 physics_inout%ulon, physics_inout%ulat, physics_inout%q(:,:,1), & 55 physics_inout%dTemp, physics_inout%dulon, physics_inout%dulat, & 56 physics_inout%dq(:,:,1), precl_packed) 57 END SUBROUTINE full_physics 58 59 SUBROUTINE write_physics 60 USE output_field_mod 61 USE physics_interface_mod 62 CALL unpack_field(f_precl, precl_packed) 63 CALL output_field("precl",f_precl) 64 END SUBROUTINE write_physics 65 66 !------------------------ Draft interface ----------------------- 67 16 68 SUBROUTINE init_physics 69 USE physics_interface_mod 17 70 IMPLICIT NONE 18 71 testcase=1 ! OK for 4.2 (moist baroclinic instability) 19 72 CALL getin("dcmip_physics",testcase) 73 nb_extra_physics_2D=1 ! precl 74 nb_extra_physics_3D=0 20 75 END SUBROUTINE init_physics 21 76 22 77 SUBROUTINE compute_phys_wrap(args) 23 78 USE physics_interface_mod 24 TYPE( physics_inout) :: args79 TYPE(t_physics_inout) :: args 25 80 CALL compute_physics(args%ngrid, args%dt_phys, args%lat, & 26 81 args%p, args%Temp, args%ulon, args%ulat, args%q(:,:,1), & 27 82 args%dTemp, args%dulon, args%dulat, args%dq(:,:,1), args%extra_2D(:,1)) 28 83 END SUBROUTINE compute_phys_wrap 84 85 !------------------ Interface-independent wrapper --------------------------- 29 86 30 87 SUBROUTINE compute_physics(ngrid,dt_phys,lat, p,Temp,u,v,q, dTemp,du,dv,dq, precl) … … 54 111 REAL(rstd) :: qfi(ngrid,llm) 55 112 56 INTEGER :: i,j,l,ll,ij113 INTEGER :: l,ll,ij 57 114 REAL(rstd) :: dt_phys, inv_dt 58 115 … … 61 118 62 119 DO l=1,llm+1 63 DO j=jj_begin,jj_end 64 DO i=ii_begin,ii_end 65 ij=(j-1)*iim+i 120 DO ij=1,ngrid 66 121 pint(ij,l)=p(ij,llm+2-l) 67 ENDDO68 122 ENDDO 69 123 ENDDO … … 71 125 DO l=1,llm 72 126 ll=llm+1-l 73 DO j=jj_begin,jj_end 74 DO i=ii_begin,ii_end 75 ij=(j-1)*iim+i 76 pmid(ij,l)=0.5*(pint(ij,l)+pint(ij,l+1)) ! Pressure inside layers 77 pdel(ij,l)=pint(ij,l+1)-pint(ij,l) ! Pressure difference between two layers 78 ufi(ij,l)=u(ij,ll) 79 vfi(ij,l)=v(ij,ll) 80 qfi(ij,l)=q(ij,ll) 81 Tfi(ij,l)=Temp(ij,ll)/(1+0.608*qfi(ij,l)) 82 ENDDO 127 DO ij=1,ngrid 128 pmid(ij,l)=0.5*(pint(ij,l)+pint(ij,l+1)) ! Pressure inside layers 129 pdel(ij,l)=pint(ij,l+1)-pint(ij,l) ! Pressure difference between two layers 130 ufi(ij,l)=u(ij,ll) 131 vfi(ij,l)=v(ij,ll) 132 qfi(ij,l)=q(ij,ll) 133 Tfi(ij,l)=Temp(ij,ll)/(1+0.608*qfi(ij,l)) 83 134 ENDDO 84 135 ENDDO … … 90 141 DO l=1,llm 91 142 ll=llm+1-l 92 DO j=jj_begin,jj_end 93 DO i=ii_begin,ii_end 94 ij=(j-1)*iim+i 95 dTemp(ij,l) = inv_dt * ( Tfi(ij,ll)*(1+0.608*qfi(ij,ll)) - Temp(ij,l) ) 96 du(ij,l) = inv_dt * (ufi(ij,ll) - u(ij,l)) 97 dv(ij,l) = inv_dt * (vfi(ij,ll) - v(ij,l)) 98 dq(ij,l) = inv_dt * (qfi(ij,ll) - q(ij,l)) 99 ENDDO 143 DO ij=1,ngrid 144 dTemp(ij,l) = inv_dt * ( Tfi(ij,ll)*(1+0.608*qfi(ij,ll)) - Temp(ij,l) ) 145 du(ij,l) = inv_dt * (ufi(ij,ll) - u(ij,l)) 146 dv(ij,l) = inv_dt * (vfi(ij,ll) - v(ij,l)) 147 dq(ij,l) = inv_dt * (qfi(ij,ll) - q(ij,l)) 100 148 ENDDO 101 149 ENDDO -
codes/icosagcm/trunk/src/physics_interface.f90
r196 r213 5 5 PRIVATE 6 6 7 TYPE :: physics_inout 8 ! Input 7 INTEGER :: nb_extra_physics_2D, nb_extra_physics_3D 8 9 TYPE t_physics_inout 10 ! Input, time-independent 9 11 INTEGER :: ngrid 10 12 REAL(rstd) :: dt_phys 11 REAL(rstd), DIMENSION(:), POINTER :: lon, lat 13 REAL(rstd), DIMENSION(:), POINTER :: Ai, lon, lat, phis 14 ! Input, time-dependent 12 15 REAL(rstd), DIMENSION(:,:), POINTER :: p, Temp, ulon, ulat 13 16 REAL(rstd), DIMENSION(:,:,:), POINTER :: q … … 18 21 REAL(rstd), DIMENSION(:,:), POINTER :: extra_2D 19 22 REAL(rstd), DIMENSION(:,:,:), POINTER :: extra_3D 20 END TYPE physics_inout 21 22 PUBLIC :: physics_inout 23 END TYPE t_physics_inout 24 25 !------------------------ (new interface) -------------------------- 26 ! physics_inout is used to exchange information with physics 27 ! Field ngrid is initialized by physics.f90/init_physics. Its other fields 28 ! must be defined by XX/init_physics (where XX = e.g. physics_dcmip.f90) 29 ! by either pointing to internal data of the physics package 30 ! or by a specific allocation 31 ! size : (ngrid), (ngrid,llm) except p(ngrid,llm+1), (ngrid,llm,nqtot) 32 33 TYPE(t_physics_inout), SAVE :: physics_inout 34 35 !------------------------ (new interface) -------------------------- 36 ! pack_info contains indices used by pack/unpack routines 37 ! to pack together the data of all the domains managed by the MPI process 38 ! It is initialized by physics.f90/init_physics 39 TYPE t_pack_info 40 INTEGER :: ngrid, & ! number of non-halo points in that domain 41 nseg ! number of segments (contigous parts) in that domain 42 ! size and start of each segment : ij domain index, k packed index 43 INTEGER, ALLOCATABLE :: n(:), ij(:), k(:) 44 END TYPE t_pack_info 45 46 TYPE(t_pack_info), ALLOCATABLE, SAVE :: pack_info(:) 47 48 INTERFACE pack_field 49 MODULE PROCEDURE pack_2D 50 MODULE PROCEDURE pack_3D 51 MODULE PROCEDURE pack_4D 52 END INTERFACE pack_field 53 54 INTERFACE unpack_field 55 MODULE PROCEDURE unpack_2D 56 MODULE PROCEDURE unpack_3D 57 MODULE PROCEDURE unpack_4D 58 END INTERFACE unpack_field 59 60 INTERFACE pack_domain 61 MODULE PROCEDURE pack_domain_2D 62 MODULE PROCEDURE pack_domain_3D 63 MODULE PROCEDURE pack_domain_4D 64 END INTERFACE pack_domain 65 66 INTERFACE unpack_domain 67 MODULE PROCEDURE unpack_domain_2D 68 MODULE PROCEDURE unpack_domain_3D 69 MODULE PROCEDURE unpack_domain_4D 70 END INTERFACE unpack_domain 71 72 PUBLIC :: nb_extra_physics_2D, nb_extra_physics_3D, & 73 t_physics_inout, physics_inout, & 74 t_pack_info, pack_info, init_pack_before, init_pack_after, & 75 pack_domain, pack_field, unpack_domain, unpack_field, & 76 garbage_3D 77 78 CONTAINS 79 80 SUBROUTINE init_pack_before 81 USE icosa 82 IMPLICIT NONE 83 INTEGER :: ind, offset 84 !$OMP MASTER 85 offset=0 86 ALLOCATE(pack_info(ndomain)) 87 DO ind=1,ndomain 88 CALL swap_dimensions(ind) 89 CALL swap_geometry(ind) 90 CALL count_segments(domain(ind)%own, pack_info(ind)) 91 pack_info(ind)%k = pack_info(ind)%k + offset 92 offset = offset + pack_info(ind)%ngrid 93 END DO 94 physics_inout%ngrid = offset 95 !$OMP END MASTER 96 !$OMP BARRIER 97 END SUBROUTINE init_pack_before 98 99 SUBROUTINE count_segments(own, info) 100 USE icosa 101 IMPLICIT NONE 102 LOGICAL, DIMENSION(:,:) :: own 103 TYPE(t_pack_info) :: info 104 105 INTEGER, DIMENSION(jjm) :: n 106 INTEGER :: ngrid, nseg, i, j, jj, k 107 INTEGER, PARAMETER :: method=4 108 SELECT CASE(method) 109 CASE(1) ! Copy all points, including halo (works) 110 info%nseg=1 111 info%ngrid=iim*jjm 112 ALLOCATE(info%n(1)) 113 ALLOCATE(info%ij(1)) 114 ALLOCATE(info%k(1)) 115 info%n(1)=iim*jjm 116 info%ij(1)=1 117 info%k(1)=1 118 CASE(2) ! Copy all points, including halo, one at a time (works, slow ?) 119 info%nseg=iim*jjm 120 info%ngrid=iim*jjm 121 ALLOCATE(info%n(iim*jjm)) 122 ALLOCATE(info%ij(iim*jjm)) 123 ALLOCATE(info%k(iim*jjm)) 124 DO jj=1,iim*jjm 125 info%n(jj) =1 126 info%ij(jj)=jj 127 info%k(jj) =jj 128 END DO 129 CASE(3) ! Copy non-halo points only, one at a time (works, slow ?) 130 n=COUNT(own,1) 131 ngrid=SUM(n) 132 info%ngrid=ngrid 133 info%nseg=ngrid 134 ALLOCATE(info%n(ngrid)) 135 ALLOCATE(info%ij(ngrid)) 136 ALLOCATE(info%k(ngrid)) 137 jj=1 138 DO j=1,jjm 139 DO i=1,iim 140 IF(own(i,j)) THEN 141 info%n(jj)=1 142 info%k(jj)=jj 143 info%ij(jj) = iim*(j-1)+i 144 jj=jj+1 145 END IF 146 END DO 147 END DO 148 149 CASE DEFAULT ! Copy non-halo points only, as contiguous segments (works) 150 n=0 151 n=COUNT(own,1) 152 ngrid=SUM(n) 153 info%ngrid=ngrid 154 nseg=COUNT(n>0) 155 info%nseg=nseg 156 ALLOCATE(info%n(nseg)) 157 ALLOCATE(info%ij(nseg)) 158 ALLOCATE(info%k(nseg)) 159 160 jj=1 161 k=1 162 DO j=1,jjm 163 IF(n(j)>0) THEN 164 ! find first .TRUE. value in own(:,j) 165 DO i=1,iim 166 IF(own(i,j)) THEN 167 info%n(jj)=n(j) 168 info%k(jj)=k 169 info%ij(jj) = iim*(j-1)+i 170 IF(COUNT(own(i:i+n(j)-1,j)) /= n(j)) STOP 171 EXIT 172 END IF 173 END DO 174 k = k + n(j) 175 jj=jj+1 176 END IF 177 END DO 178 179 IF(k-1/=ngrid) THEN 180 PRINT *, 'Total number of grid points inconsistent', k-1, ngrid 181 STOP 182 END IF 183 IF(jj-1/=nseg) THEN 184 PRINT *, 'Number of segments inconsistent', jj-1, nseg 185 STOP 186 END IF 187 188 END SELECT 189 190 PRINT *, 'count_segments', info%nseg, info%ngrid, SUM(info%n), COUNT(own), iim*jjm 191 END SUBROUTINE count_segments 192 193 SUBROUTINE init_pack_after 194 USE icosa 195 IMPLICIT NONE 196 INTEGER :: ind, offset 197 DO ind=1,ndomain 198 IF (.NOT. assigned_domain(ind)) CYCLE 199 CALL swap_dimensions(ind) 200 CALL swap_geometry(ind) 201 CALL pack_domain_2D(pack_info(ind), Ai, physics_inout%Ai) 202 CALL pack_lonlat(pack_info(ind)) 203 END DO 204 END SUBROUTINE init_pack_after 205 206 SUBROUTINE pack_lonlat(info) 207 USE icosa 208 IMPLICIT NONE 209 TYPE(t_pack_info) :: info 210 REAL(rstd) :: lon(iim*jjm), lat(iim*jjm) 211 INTEGER :: ij 212 DO ij=1,iim*jjm 213 CALL xyz2lonlat(xyz_i(ij,:),lon(ij),lat(ij)) 214 ENDDO 215 CALL pack_domain_2D(info, lon, physics_inout%lon) 216 CALL pack_domain_2D(info, lat, physics_inout%lat) 217 END SUBROUTINE pack_lonlat 218 219 !-------------------------------- Pack / Unpack 2D --------------------------- 220 221 SUBROUTINE pack_2D(f_2D, packed) 222 USE icosa 223 IMPLICIT NONE 224 TYPE(t_field),POINTER :: f_2D(:) 225 REAL(rstd) :: packed(:) 226 REAL(rstd), POINTER :: loc(:) 227 INTEGER :: ind 228 DO ind=1,ndomain 229 IF (.NOT. assigned_domain(ind)) CYCLE 230 loc = f_2D(ind) 231 CALL pack_domain_2D(pack_info(ind), loc, packed) 232 END DO 233 END SUBROUTINE pack_2D 234 235 SUBROUTINE unpack_2D(f_2D, packed) 236 USE icosa 237 IMPLICIT NONE 238 TYPE(t_field),POINTER :: f_2D(:) 239 REAL(rstd) :: packed(:) 240 REAL(rstd), POINTER :: loc(:) 241 INTEGER :: ind 242 DO ind=1,ndomain 243 IF (.NOT. assigned_domain(ind)) CYCLE 244 loc = f_2D(ind) 245 CALL unpack_domain_2D(pack_info(ind), loc, packed) 246 END DO 247 END SUBROUTINE unpack_2D 248 249 SUBROUTINE pack_domain_2D(info, loc, glob) 250 USE icosa 251 IMPLICIT NONE 252 TYPE(t_pack_info) :: info 253 REAL(rstd), DIMENSION(:) :: loc, glob 254 INTEGER :: jj,n,k,ij 255 DO jj=1, info%nseg 256 n = info%n(jj)-1 257 ij = info%ij(jj) 258 k = info%k(jj) 259 glob(k:k+n) = loc(ij:ij+n) 260 END DO 261 END SUBROUTINE pack_domain_2D 262 263 SUBROUTINE unpack_domain_2D(info, loc, glob) 264 IMPLICIT NONE 265 TYPE(t_pack_info) :: info 266 REAL(rstd), DIMENSION(:) :: loc, glob 267 INTEGER :: jj,n,k,ij 268 DO jj=1, info%nseg 269 n = info%n(jj)-1 270 ij = info%ij(jj) 271 k = info%k(jj) 272 loc(ij:ij+n) = glob(k:k+n) 273 END DO 274 END SUBROUTINE unpack_domain_2D 275 276 !-------------------------------- Pack / Unpack 3D --------------------------- 277 278 SUBROUTINE pack_3D(f_3D, packed) 279 USE icosa 280 IMPLICIT NONE 281 TYPE(t_field),POINTER :: f_3D(:) 282 REAL(rstd) :: packed(:,:) 283 REAL(rstd), POINTER :: loc(:,:) 284 INTEGER :: ind 285 DO ind=1,ndomain 286 IF (.NOT. assigned_domain(ind)) CYCLE 287 loc = f_3D(ind) 288 CALL pack_domain_3D(pack_info(ind), loc, packed) 289 END DO 290 END SUBROUTINE pack_3D 291 292 SUBROUTINE unpack_3D(f_3D, packed) 293 USE icosa 294 IMPLICIT NONE 295 TYPE(t_field),POINTER :: f_3D(:) 296 REAL(rstd) :: packed(:,:) 297 REAL(rstd), POINTER :: loc(:,:) 298 INTEGER :: ind 299 DO ind=1,ndomain 300 IF (.NOT. assigned_domain(ind)) CYCLE 301 loc = f_3D(ind) 302 CALL unpack_domain_3D(pack_info(ind), loc, packed) 303 END DO 304 END SUBROUTINE unpack_3D 305 306 SUBROUTINE pack_domain_3D(info, loc, glob) 307 IMPLICIT NONE 308 TYPE(t_pack_info) :: info 309 REAL(rstd), DIMENSION(:,:) :: loc, glob 310 INTEGER :: jj,n,k,ij 311 DO jj=1, info%nseg 312 n = info%n(jj)-1 313 ij = info%ij(jj) 314 k = info%k(jj) 315 glob(k:k+n,:) = loc(ij:ij+n,:) 316 END DO 317 END SUBROUTINE pack_domain_3D 318 319 SUBROUTINE unpack_domain_3D(info, loc, glob) 320 IMPLICIT NONE 321 TYPE(t_pack_info) :: info 322 REAL(rstd), DIMENSION(:,:) :: loc, glob 323 INTEGER :: jj,n,k,ij 324 DO jj=1, info%nseg 325 n = info%n(jj)-1 326 ij = info%ij(jj) 327 k = info%k(jj) 328 loc(ij:ij+n,:) = glob(k:k+n,:) 329 END DO 330 END SUBROUTINE unpack_domain_3D 331 332 SUBROUTINE garbage_3D(loc,own) 333 USE icosa 334 IMPLICIT NONE 335 LOGICAL :: own(iim,jjm) 336 REAL(rstd) :: loc(iim*jjm,llm) 337 INTEGER :: i,j,ij 338 ! write garbage in non-owned points 339 DO j=1,jjm 340 DO i=1,iim 341 IF(.NOT.own(i,j)) THEN 342 ij=iim*(j-1)+i 343 loc(ij,:)=-1e30 344 END IF 345 END DO 346 END DO 347 END SUBROUTINE garbage_3D 348 349 !-------------------------------- Pack / Unpack 4D --------------------------- 350 351 SUBROUTINE pack_4D(f_4D, packed) 352 USE icosa 353 IMPLICIT NONE 354 TYPE(t_field),POINTER :: f_4D(:) 355 REAL(rstd) :: packed(:,:,:) 356 REAL(rstd), POINTER :: loc(:,:,:) 357 INTEGER :: ind 358 DO ind=1,ndomain 359 IF (.NOT. assigned_domain(ind)) CYCLE 360 loc = f_4D(ind) 361 CALL pack_domain_4D(pack_info(ind), loc, packed) 362 END DO 363 END SUBROUTINE pack_4D 364 365 SUBROUTINE unpack_4D(f_4D, packed) 366 USE icosa 367 IMPLICIT NONE 368 TYPE(t_field),POINTER :: f_4D(:) 369 REAL(rstd) :: packed(:,:,:) 370 REAL(rstd), POINTER :: loc(:,:,:) 371 INTEGER :: ind 372 DO ind=1,ndomain 373 IF (.NOT. assigned_domain(ind)) CYCLE 374 loc = f_4D(ind) 375 CALL unpack_domain_4D(pack_info(ind), loc, packed) 376 END DO 377 END SUBROUTINE unpack_4D 378 379 SUBROUTINE pack_domain_4D(info, loc, glob) 380 IMPLICIT NONE 381 TYPE(t_pack_info) :: info 382 REAL(rstd), DIMENSION(:,:,:) :: loc, glob 383 INTEGER :: jj,n,k,ij 384 DO jj=1, info%nseg 385 n = info%n(jj)-1 386 ij = info%ij(jj) 387 k = info%k(jj) 388 glob(k:k+n,:,:) = loc(ij:ij+n,:,:) 389 END DO 390 END SUBROUTINE pack_domain_4D 391 392 SUBROUTINE unpack_domain_4D(info, loc, glob) 393 IMPLICIT NONE 394 TYPE(t_pack_info) :: info 395 REAL(rstd), DIMENSION(:,:,:) :: loc, glob 396 INTEGER :: jj,n,k,ij 397 DO jj=1, info%nseg 398 n = info%n(jj)-1 399 ij = info%ij(jj) 400 k = info%k(jj) 401 loc(ij:ij+n,:,:) = glob(k:k+n,:,:) 402 END DO 403 END SUBROUTINE unpack_domain_4D 23 404 24 405 END MODULE physics_interface_mod
Note: See TracChangeset
for help on using the changeset viewer.