Ignore:
Timestamp:
02/16/13 17:03:57 (11 years ago)
Author:
dubos
Message:

Transport now working again - tested with dcmip4.1.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • codes/icosagcm/trunk/src/advect_tracer.f90

    r137 r138  
    11MODULE advect_tracer_mod 
    22  USE icosa 
     3  IMPLICIT NONE 
    34  PRIVATE 
    45 
     
    89  TYPE(t_field),POINTER :: f_cc(:)  ! starting point of backward-trajectory (Miura approach) 
    910 
    10 !  TYPE(t_field),POINTER :: f_rhodzm1(:) 
    11 !  TYPE(t_field),POINTER :: f_rhodz(:) 
    12  
    1311  REAL(rstd), PARAMETER :: pente_max=2.0 ! for vlz 
    1412 
     
    1917  SUBROUTINE init_advect_tracer 
    2018    USE advect_mod 
    21     IMPLICIT NONE 
    2219    REAL(rstd),POINTER :: tangent(:,:) 
    2320    REAL(rstd),POINTER :: normal(:,:) 
    2421    INTEGER :: ind 
    2522 
    26     CALL allocate_field(f_normal,field_u,type_real,3) 
    27     CALL allocate_field(f_tangent,field_u,type_real,3) 
    28     CALL allocate_field(f_gradq3d,field_t,type_real,llm,3) 
    29     CALL allocate_field(f_cc,field_u,type_real,llm,3) 
    30  
    31 !    CALL allocate_field(f_rhodz,field_t,type_real,llm)  
    32 !    CALL allocate_field(f_rhodzm1,field_t,type_real,llm)  
     23    CALL allocate_field(f_normal,field_u,type_real,3, name='normal') 
     24    CALL allocate_field(f_tangent,field_u,type_real,3, name='tangent') 
     25    CALL allocate_field(f_gradq3d,field_t,type_real,llm,3, name='gradq3d') 
     26    CALL allocate_field(f_cc,field_u,type_real,llm,3, name='cc') 
    3327 
    3428    DO ind=1,ndomain 
     
    4337 
    4438  SUBROUTINE advect_tracer(f_hfluxt, f_wfluxt,f_u, f_q,f_rhodz) 
    45     USE icosa 
    46     USE field_mod 
    47     USE domain_mod 
    48     USE dimensions 
    49     USE grid_param 
    50     USE geometry 
    51     USE metric 
    5239    USE advect_mod 
    53     USE advect_mod 
    54     USE disvert_mod 
    5540    USE mpipara 
    5641    IMPLICIT NONE 
     
    6247    TYPE(t_field),POINTER :: f_rhodz(:)    ! mass field at beginning of macro time step 
    6348 
    64     REAL(rstd),POINTER :: q(:,:,:), normal(:,:,:), tangent(:,:,:), gradq3d(:,:,:) 
     49    REAL(rstd),POINTER :: q(:,:,:), normal(:,:), tangent(:,:), gradq3d(:,:,:), cc(:,:,:) 
    6550    REAL(rstd),POINTER :: hfluxt(:,:), wfluxt(:,:) 
    6651    REAL(rstd),POINTER :: rhodz(:,:), u(:,:)  
    67     INTEGER :: ind 
     52    INTEGER :: ind,k 
    6853 
    6954    CALL transfert_request(f_u,req_e1) 
    70     CALL transfert_request(f_u,req_e1) 
     55!    CALL transfert_request(f_hfluxt,req_e1)  ! BUG : This (unnecessary) transfer makes the computation go wrong 
     56    CALL transfert_request(f_wfluxt,req_i1) 
    7157    CALL transfert_request(f_q,req_i1) 
     58    CALL transfert_request(f_rhodz,req_i1) 
    7259         
    7360    IF (is_mpi_root) PRINT *, 'Advection scheme' 
    7461 
     62!    DO ind=1,ndomain 
     63!       CALL swap_dimensions(ind) 
     64!       CALL swap_geometry(ind) 
     65!       normal  = f_normal(ind) 
     66!       tangent = f_tangent(ind) 
     67!       cc      = f_cc(ind) 
     68!       u       = f_u(ind) 
     69!       q       = f_q(ind) 
     70!       rhodz   = f_rhodz(ind) 
     71!       hfluxt  = f_hfluxt(ind)  
     72!       wfluxt  = f_wfluxt(ind)  
     73!       gradq3d = f_gradq3d(ind) 
     74! 
     75!       ! 1/2 vertical transport 
     76!       DO k = 1, nqtot 
     77!          CALL vlz(k==nqtot,0.5, wfluxt,rhodz,q(:,:,k)) 
     78!       END DO 
     79! 
     80!       ! horizontal transport 
     81!       CALL compute_backward_traj(tangent,normal,u,0.5*dt*itau_adv, cc)  
     82!       DO k = 1,nqtot 
     83!          CALL compute_gradq3d(q(:,:,k),gradq3d) 
     84!          CALL compute_advect_horiz(k==nqtot,hfluxt,cc,gradq3d, rhodz,q(:,:,k)) 
     85!       END DO 
     86! 
     87!       ! 1/2 vertical transport 
     88!       DO k = 1,nqtot 
     89!          CALL vlz(k==nqtot, 0.5,wfluxt,rhodz, q(:,:,k)) 
     90!       END DO 
     91!    END DO 
     92 
     93    ! 1/2 vertical transport + back-trajectories 
     94    DO ind=1,ndomain 
     95       CALL swap_dimensions(ind) 
     96       CALL swap_geometry(ind) 
     97       normal  = f_normal(ind) 
     98       tangent = f_tangent(ind) 
     99       cc      = f_cc(ind) 
     100       u       = f_u(ind) 
     101       q       = f_q(ind) 
     102       rhodz   = f_rhodz(ind) 
     103       wfluxt  = f_wfluxt(ind)  
     104       DO k = 1, nqtot 
     105          CALL vlz(k==nqtot,0.5, wfluxt,rhodz,q(:,:,k)) 
     106       END DO 
     107       CALL compute_backward_traj(tangent,normal,u,0.5*dt*itau_adv, cc)  
     108    END DO 
     109 
     110    CALL transfert_request(f_q,req_i1)      ! necessary ? 
     111    CALL transfert_request(f_rhodz,req_i1)  ! necessary ? 
     112 
     113    ! horizontal transport - split in two to place transfer of gradq3d 
     114 
     115    DO k = 1, nqtot 
     116       DO ind=1,ndomain 
     117          CALL swap_dimensions(ind) 
     118          CALL swap_geometry(ind) 
     119          q       = f_q(ind) 
     120          gradq3d = f_gradq3d(ind) 
     121          CALL compute_gradq3d(q(:,:,k),gradq3d) 
     122       END DO 
     123 
     124       CALL transfert_request(f_gradq3d,req_i1) 
     125 
     126       DO ind=1,ndomain 
     127          CALL swap_dimensions(ind) 
     128          CALL swap_geometry(ind) 
     129          cc      = f_cc(ind) 
     130          q       = f_q(ind) 
     131          rhodz   = f_rhodz(ind) 
     132          hfluxt  = f_hfluxt(ind)  
     133          gradq3d = f_gradq3d(ind) 
     134          CALL compute_advect_horiz(k==nqtot,hfluxt,cc,gradq3d, rhodz,q(:,:,k)) 
     135       END DO 
     136    END DO  
     137 
     138    CALL transfert_request(f_q,req_i1)      ! necessary ? 
     139    CALL transfert_request(f_rhodz,req_i1)  ! necessary ? 
     140 
     141    ! 1/2 vertical transport 
    75142    DO ind=1,ndomain 
    76143       CALL swap_dimensions(ind) 
     
    78145       q       = f_q(ind) 
    79146       rhodz   = f_rhodz(ind) 
    80        hfluxt  = f_hfluxt(ind)  
    81147       wfluxt  = f_wfluxt(ind)  
    82        normal  = f_normal(ind) 
    83        tangent = f_tangent(ind) 
    84        gradq3d = f_gradq3d(ind) 
    85        CALL compute_adv_tracer(tangent,normal,hfluxt,wfluxt,u, q,rhodz,gradq3d) 
     148       DO k = 1,nqtot 
     149          CALL vlz(k==nqtot, 0.5,wfluxt,rhodz, q(:,:,k)) 
     150       END DO 
    86151    END DO 
    87152 
    88153  END SUBROUTINE advect_tracer 
    89154 
    90   SUBROUTINE compute_adv_tracer(tangent,normal,hfluxt,wfluxt,u, q,rhodz,gradq3d) 
    91     USE icosa 
    92     USE field_mod 
    93     USE domain_mod 
    94     USE dimensions 
    95     USE grid_param 
    96     USE geometry 
    97     USE metric 
    98     USE advect_mod 
    99     USE advect_mod 
    100     USE disvert_mod 
    101     USE mpipara 
    102     REAL(rstd), INTENT(IN) :: tangent(:,:,:), normal(:,:,:) 
    103     REAL(rstd), INTENT(IN) :: hfluxt(:,:), wfluxt(:,:), u(:,:) 
    104     REAL(rstd), INTENT(INOUT) :: rhodz(:,:) 
    105     REAL(rstd), INTENT(INOUT) :: q(:,:,:) 
    106     REAL(rstd), INTENT(OUT)   :: gradq3d(:,:,:) 
    107     INTEGER :: k 
    108     ! for mass/tracer consistency each transport step also updates the mass field rhodz 
    109     ! mass is updated after all tracers have been updated, when k==nqtot 
    110  
    111     ! 1/2 vertical transport 
    112     DO k = 1, nqtot 
    113        CALL vlz(k==nqtot, 0.5,wfluxt,rhodz,q(:,:,k)) 
    114     END DO 
    115  
    116     ! horizontal transport 
    117     DO k = 1,nqtot 
    118        CALL compute_gradq3d(q(:,:,k),gradq3d) 
    119        CALL compute_advect_horiz(k==nqtot, tangent,normal,q(:,:,k),gradq3d,rhodz,u,hfluxt,dt*itau_adv)  
    120     END DO 
    121  
    122     ! 1/2 vertical transport 
    123     DO k = 1,nqtot 
    124        CALL vlz(k==nqtot, 0.5,wfluxt,rhodz, q(:,:,k)) 
    125     END DO 
    126   END SUBROUTINE compute_adv_tracer 
    127    
    128155  SUBROUTINE vlz(update_mass, fac,wfluxt,mass, q) 
    129156    ! 
     
    135162    !     wfluxt >0 for upward transport 
    136163    !    ******************************************************************** 
    137     USE icosa 
    138164    IMPLICIT NONE 
    139165    LOGICAL, INTENT(IN)       :: update_mass 
     
    152178    ! finite difference of q 
    153179    DO l=2,llm 
    154        DO j=jj_begin,jj_end 
    155           DO i=ii_begin,ii_end 
     180       DO j=jj_begin-1,jj_end+1 
     181          DO i=ii_begin-1,ii_end+1 
    156182             ij=(j-1)*iim+i 
    157183             dzqw(ij,l)=q(ij,l)-q(ij,l-1) 
     
    164190    ! dzq = slope*dz, i.e. the reconstructed q varies by dzq inside level l 
    165191    DO l=2,llm-1 
    166        DO j=jj_begin,jj_end 
    167           DO i=ii_begin,ii_end 
     192       DO j=jj_begin-1,jj_end+1 
     193          DO i=ii_begin-1,ii_end+1 
    168194             ij=(j-1)*iim+i 
    169195             IF(dzqw(ij,l)*dzqw(ij,l+1).gt.0.) THEN 
     
    179205 
    180206    ! 0 slope in top and bottom layers 
    181     DO j=jj_begin,jj_end 
    182        DO i=ii_begin,ii_end 
     207    DO j=jj_begin-1,jj_end+1 
     208       DO i=ii_begin-1,ii_end+1 
    183209          ij=(j-1)*iim+i 
    184210          dzq(ij,1)=0. 
     
    190216    ! then amount of q leaving level l/l+1 = wq = w * qq 
    191217    DO l = 1,llm-1 
    192        DO j=jj_begin,jj_end 
    193           DO i=ii_begin,ii_end 
    194              ij=(j-1)*iim+i 
    195              IF(wfluxt(ij,l+1).gt.0.) THEN 
    196                 ! downward transport, sigw<0 
    197                 ! qq = q if sigw=-1 , qq = q-dzq/2 if sigw=0                 
    198                 w          = fac*wfluxt(ij,l+1) 
     218       DO j=jj_begin-1,jj_end+1 
     219          DO i=ii_begin-1,ii_end+1 
     220             ij=(j-1)*iim+i 
     221             w = fac*wfluxt(ij,l+1) 
     222             IF(w>0.) THEN  ! upward transport, upwind side is at level l  
     223                sigw       = w/mass(ij,l) 
     224                qq         = q(ij,l)+0.5*(1.-sigw)*dzq(ij,l) ! qq = q if sigw=1 , qq = q+dzq/2 if sigw=0 
     225             ELSE           ! downward transport, upwind side is at level l+1 
    199226                sigw       = w/mass(ij,l+1) 
    200                 qq         = q(ij,l+1) - 0.5*(1.+sigw)*dzq(ij,l+1) 
    201                 wq(ij,l+1) = w*qq 
    202              ELSE 
    203                 ! upward transport, sigw>0 
    204                 ! qq = q if sigw=1 , qq = q+dzq/2 if sigw=0 
    205                 w          = fac*wfluxt(ij,l) 
    206                 sigw       = w/mass(ij,l) 
    207                 qq         = q(ij,l)+0.5*(1.-sigw)*dzq(ij,l) 
    208                 wq(ij,l+1) = w*qq 
     227                qq         = q(ij,l+1)-0.5*(1.+sigw)*dzq(ij,l+1) ! qq = q if sigw=-1 , qq = q-dzq/2 if sigw=0                 
    209228             ENDIF 
     229             wq(ij,l+1) = w*qq 
    210230          ENDDO 
    211231       ENDDO 
    212232    END DO 
    213233    ! wq = 0 at top and bottom 
    214     DO j=jj_begin,jj_end 
    215        DO i=ii_begin,ii_end 
     234    DO j=jj_begin-1,jj_end+1 
     235       DO i=ii_begin-1,ii_end+1 
    216236          ij=(j-1)*iim+i 
    217237          wq(ij,llm+1)=0. 
     
    222242    ! update q, mass is updated only after all q's have been updated 
    223243    DO l=1,llm 
    224        DO j=jj_begin,jj_end 
    225           DO i=ii_begin,ii_end 
     244       DO j=jj_begin-1,jj_end+1 
     245          DO i=ii_begin-1,ii_end+1 
    226246             ij=(j-1)*iim+i 
    227247             newmass = mass(ij,l) + fac*(wfluxt(ij,l)-wfluxt(ij,l+1)) 
Note: See TracChangeset for help on using the changeset viewer.