New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
dtatsd.F90 in trunk/NEMOGCM/NEMO/OPA_SRC/DOM – NEMO

source: trunk/NEMOGCM/NEMO/OPA_SRC/DOM/dtatsd.F90 @ 7698

Last change on this file since 7698 was 7698, checked in by mocavero, 7 years ago

update trunk with OpenMP parallelization

  • Property svn:keywords set to Id
File size: 14.2 KB
RevLine 
[3132]1MODULE dtatsd
2   !!======================================================================
3   !!                     ***  MODULE  dtatsd  ***
4   !! Ocean data  :  read ocean Temperature & Salinity Data from gridded data
5   !!======================================================================
6   !! History :  OPA  ! 1991-03  ()  Original code
7   !!             -   ! 1992-07  (M. Imbard)
8   !!            8.0  ! 1999-10  (M.A. Foujols, M. Imbard)  NetCDF FORMAT
9   !!   NEMO     1.0  ! 2002-06  (G. Madec)  F90: Free form and module
10   !!            3.3  ! 2010-10  (C. Bricaud, S. Masson)  use of fldread
11   !!            3.4  ! 2010-11  (G. Madec, C. Ethe) Merge of dtatem and dtasal + suppression of CPP keys
12   !!----------------------------------------------------------------------
13
14   !!----------------------------------------------------------------------
15   !!   dta_tsd      : read and time interpolated ocean Temperature & Salinity Data
16   !!----------------------------------------------------------------------
17   USE oce             ! ocean dynamics and tracers
18   USE dom_oce         ! ocean space and time domain
19   USE fldread         ! read input fields
20   USE in_out_manager  ! I/O manager
21   USE phycst          ! physical constants
22   USE lib_mpp         ! MPP library
[3186]23   USE wrk_nemo        ! Memory allocation
[3162]24   USE timing          ! Timing
[3132]25
26   IMPLICIT NONE
27   PRIVATE
28
29   PUBLIC   dta_tsd_init   ! called by opa.F90
30   PUBLIC   dta_tsd        ! called by istate.F90 and tradmp.90
31
[4147]32   LOGICAL , PUBLIC ::   ln_tsd_init      !: T & S data flag
33   LOGICAL , PUBLIC ::   ln_tsd_tradmp    !: internal damping toward input data flag
[3132]34
35   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_tsd   ! structure of input SST (file informations, fields read)
36
37   !!----------------------------------------------------------------------
38   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
[5215]39   !! $Id$
[3132]40   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
41   !!----------------------------------------------------------------------
42CONTAINS
43
44   SUBROUTINE dta_tsd_init( ld_tradmp )
45      !!----------------------------------------------------------------------
46      !!                   ***  ROUTINE dta_tsd_init  ***
47      !!                   
48      !! ** Purpose :   initialisation of T & S input data
49      !!
50      !! ** Method  : - Read namtsd namelist
51      !!              - allocates T & S data structure
52      !!----------------------------------------------------------------------
53      LOGICAL, INTENT(in), OPTIONAL ::   ld_tradmp   ! force the initialization when tradp is used
54      !
[7646]55      INTEGER ::   ios, ierr0, ierr1, ierr2, ierr3   ! local integers
56      !!
[3132]57      CHARACTER(len=100)            ::   cn_dir          ! Root directory for location of ssr files
58      TYPE(FLD_N), DIMENSION( jpts) ::   slf_i           ! array of namelist informations on the fields to read
59      TYPE(FLD_N)                   ::   sn_tem, sn_sal
60      !!
61      NAMELIST/namtsd/   ln_tsd_init, ln_tsd_tradmp, cn_dir, sn_tem, sn_sal
62      !!----------------------------------------------------------------------
[3162]63      !
64      IF( nn_timing == 1 )  CALL timing_start('dta_tsd_init')
65      !
[3266]66      !  Initialisation
67      ierr0 = 0  ;  ierr1 = 0  ;  ierr2 = 0  ;  ierr3 = 0
68      !
[4147]69      REWIND( numnam_ref )              ! Namelist namtsd in reference namelist :
70      READ  ( numnam_ref, namtsd, IOSTAT = ios, ERR = 901)
71901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtsd in reference namelist', lwp )
[3132]72
[4147]73      REWIND( numnam_cfg )              ! Namelist namtsd in configuration namelist : Parameters of the run
74      READ  ( numnam_cfg, namtsd, IOSTAT = ios, ERR = 902 )
75902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtsd in configuration namelist', lwp )
[4624]76      IF(lwm) WRITE ( numond, namtsd )
[3132]77
78      IF( PRESENT( ld_tradmp ) )   ln_tsd_tradmp = .TRUE.     ! forces the initialization when tradmp is used
79     
80      IF(lwp) THEN                  ! control print
81         WRITE(numout,*)
82         WRITE(numout,*) 'dta_tsd_init : Temperature & Salinity data '
83         WRITE(numout,*) '~~~~~~~~~~~~ '
84         WRITE(numout,*) '   Namelist namtsd'
85         WRITE(numout,*) '      Initialisation of ocean T & S with T &S input data   ln_tsd_init   = ', ln_tsd_init
86         WRITE(numout,*) '      damping of ocean T & S toward T &S input data        ln_tsd_tradmp = ', ln_tsd_tradmp
87         WRITE(numout,*)
88         IF( .NOT.ln_tsd_init .AND. .NOT.ln_tsd_tradmp ) THEN
89            WRITE(numout,*)
90            WRITE(numout,*) '   T & S data not used'
91         ENDIF
92      ENDIF
93      !
94      IF( ln_rstart .AND. ln_tsd_init ) THEN
95         CALL ctl_warn( 'dta_tsd_init: ocean restart and T & S data intialisation, ',   &
96            &           'we keep the restart T & S values and set ln_tsd_init to FALSE' )
97         ln_tsd_init = .FALSE.
98      ENDIF
99      !
100      !                             ! allocate the arrays (if necessary)
101      IF(  ln_tsd_init .OR. ln_tsd_tradmp  ) THEN
102         !
103         ALLOCATE( sf_tsd(jpts), STAT=ierr0 )
104         IF( ierr0 > 0 ) THEN
105            CALL ctl_stop( 'dta_tsd_init: unable to allocate sf_tsd structure' )   ;   RETURN
106         ENDIF
107         !
108                                ALLOCATE( sf_tsd(jp_tem)%fnow(jpi,jpj,jpk)   , STAT=ierr0 )
109         IF( sn_tem%ln_tint )   ALLOCATE( sf_tsd(jp_tem)%fdta(jpi,jpj,jpk,2) , STAT=ierr1 )
110                                ALLOCATE( sf_tsd(jp_sal)%fnow(jpi,jpj,jpk)   , STAT=ierr2 )
111         IF( sn_sal%ln_tint )   ALLOCATE( sf_tsd(jp_sal)%fdta(jpi,jpj,jpk,2) , STAT=ierr3 )
112         !
113         IF( ierr0 + ierr1 + ierr2 + ierr3 > 0 ) THEN
114            CALL ctl_stop( 'dta_tsd : unable to allocate T & S data arrays' )   ;   RETURN
115         ENDIF
116         !                         ! fill sf_tsd with sn_tem & sn_sal and control print
117         slf_i(jp_tem) = sn_tem   ;   slf_i(jp_sal) = sn_sal
[7646]118         CALL fld_fill( sf_tsd, slf_i, cn_dir, 'dta_tsd', 'Temperature & Salinity data', 'namtsd', no_print )
[3132]119         !
120      ENDIF
121      !
[3162]122      IF( nn_timing == 1 )  CALL timing_stop('dta_tsd_init')
123      !
[3132]124   END SUBROUTINE dta_tsd_init
125
126
127   SUBROUTINE dta_tsd( kt, ptsd )
128      !!----------------------------------------------------------------------
129      !!                   ***  ROUTINE dta_tsd  ***
130      !!                   
131      !! ** Purpose :   provides T and S data at kt
132      !!
133      !! ** Method  : - call fldread routine
134      !!              - ORCA_R2: add some hand made alteration to read data 
135      !!              - 'key_orca_lev10' interpolates on 10 times more levels
136      !!              - s- or mixed z-s coordinate: vertical interpolation on model mesh
137      !!              - ln_tsd_tradmp=F: deallocates the T-S data structure
138      !!                as T-S data are no are used
139      !!
140      !! ** Action  :   ptsd   T-S data on medl mesh and interpolated at time-step kt
141      !!----------------------------------------------------------------------
142      INTEGER                              , INTENT(in   ) ::   kt     ! ocean time-step
143      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(  out) ::   ptsd   ! T & S data
144      !
145      INTEGER ::   ji, jj, jk, jl, jkk   ! dummy loop indicies
146      INTEGER ::   ik, il0, il1, ii0, ii1, ij0, ij1   ! local integers
147      REAL(wp)::   zl, zi
[3162]148      REAL(wp), POINTER, DIMENSION(:) ::  ztp, zsp   ! 1D workspace
[3132]149      !!----------------------------------------------------------------------
150      !
[3162]151      IF( nn_timing == 1 )  CALL timing_start('dta_tsd')
152      !
[3132]153      CALL fld_read( kt, 1, sf_tsd )      !==   read T & S data at kt time step   ==!
154      !
155      !
[7646]156!!gm  This should be removed from the code   ===>>>>  T & S files has to be changed
157      !
[3132]158      !                                   !==   ORCA_R2 configuration and T & S damping   ==!
[7646]159      IF( cn_cfg == "orca" .AND. nn_cfg == 2 .AND. ln_tsd_tradmp ) THEN    ! some hand made alterations
[3132]160         !
161         ij0 = 101   ;   ij1 = 109                       ! Reduced T & S in the Alboran Sea
162         ii0 = 141   ;   ii1 = 155
[7698]163!$OMP PARALLEL DO schedule(static) private(jj, ji)
[3132]164         DO jj = mj0(ij0), mj1(ij1)
165            DO ji = mi0(ii0), mi1(ii1)
166               sf_tsd(jp_tem)%fnow(ji,jj,13:13) = sf_tsd(jp_tem)%fnow(ji,jj,13:13) - 0.20_wp
167               sf_tsd(jp_tem)%fnow(ji,jj,14:15) = sf_tsd(jp_tem)%fnow(ji,jj,14:15) - 0.35_wp
168               sf_tsd(jp_tem)%fnow(ji,jj,16:25) = sf_tsd(jp_tem)%fnow(ji,jj,16:25) - 0.40_wp
169               !
170               sf_tsd(jp_sal)%fnow(ji,jj,13:13) = sf_tsd(jp_sal)%fnow(ji,jj,13:13) - 0.15_wp
171               sf_tsd(jp_sal)%fnow(ji,jj,14:15) = sf_tsd(jp_sal)%fnow(ji,jj,14:15) - 0.25_wp
172               sf_tsd(jp_sal)%fnow(ji,jj,16:17) = sf_tsd(jp_sal)%fnow(ji,jj,16:17) - 0.30_wp
173               sf_tsd(jp_sal)%fnow(ji,jj,18:25) = sf_tsd(jp_sal)%fnow(ji,jj,18:25) - 0.35_wp
174            END DO
175         END DO
[5836]176         ij0 =  87   ;   ij1 =  96                          ! Reduced temperature in Red Sea
177         ii0 = 148   ;   ii1 = 160
178         sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ,  4:10 ) = 7.0_wp
179         sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 11:13 ) = 6.5_wp
180         sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 14:20 ) = 6.0_wp
[3132]181      ENDIF
[7646]182!!gm end
[3132]183      !
[7698]184!$OMP PARALLEL DO schedule(static) private(jk, jj, ji)
185      DO jk = 1, jpk
186         DO jj = 1, jpj
187            DO ji = 1, jpi
188               ptsd(ji,jj,jk,jp_tem) = sf_tsd(jp_tem)%fnow(ji,jj,jk)    ! NO mask
189               ptsd(ji,jj,jk,jp_sal) = sf_tsd(jp_sal)%fnow(ji,jj,jk)
190            END DO
191         END DO
192      END DO
[3132]193      !
194      IF( ln_sco ) THEN                   !==   s- or mixed s-zps-coordinate   ==!
195         !
[3162]196         CALL wrk_alloc( jpk, ztp, zsp )
197         !
[3132]198         IF( kt == nit000 .AND. lwp )THEN
199            WRITE(numout,*)
200            WRITE(numout,*) 'dta_tsd: interpolates T & S data onto the s- or mixed s-z-coordinate mesh'
201         ENDIF
202         !
[7698]203!$OMP PARALLEL DO schedule(static) private(jj, ji, jk, zl, jkk, zi)
[3132]204         DO jj = 1, jpj                         ! vertical interpolation of T & S
205            DO ji = 1, jpi
206               DO jk = 1, jpk                        ! determines the intepolated T-S profiles at each (i,j) points
[4292]207                  zl = gdept_0(ji,jj,jk)
208                  IF(     zl < gdept_1d(1  ) ) THEN          ! above the first level of data
[3132]209                     ztp(jk) =  ptsd(ji,jj,1    ,jp_tem)
210                     zsp(jk) =  ptsd(ji,jj,1    ,jp_sal)
[4292]211                  ELSEIF( zl > gdept_1d(jpk) ) THEN          ! below the last level of data
[3132]212                     ztp(jk) =  ptsd(ji,jj,jpkm1,jp_tem)
213                     zsp(jk) =  ptsd(ji,jj,jpkm1,jp_sal)
214                  ELSE                                      ! inbetween : vertical interpolation between jkk & jkk+1
215                     DO jkk = 1, jpkm1                                  ! when  gdept(jkk) < zl < gdept(jkk+1)
[4292]216                        IF( (zl-gdept_1d(jkk)) * (zl-gdept_1d(jkk+1)) <= 0._wp ) THEN
217                           zi = ( zl - gdept_1d(jkk) ) / (gdept_1d(jkk+1)-gdept_1d(jkk))
[3132]218                           ztp(jk) = ptsd(ji,jj,jkk,jp_tem) + ( ptsd(ji,jj,jkk+1,jp_tem) - ptsd(ji,jj,jkk,jp_tem) ) * zi 
219                           zsp(jk) = ptsd(ji,jj,jkk,jp_sal) + ( ptsd(ji,jj,jkk+1,jp_sal) - ptsd(ji,jj,jkk,jp_sal) ) * zi
220                        ENDIF
221                     END DO
222                  ENDIF
223               END DO
224               DO jk = 1, jpkm1
225                  ptsd(ji,jj,jk,jp_tem) = ztp(jk) * tmask(ji,jj,jk)     ! mask required for mixed zps-s-coord
226                  ptsd(ji,jj,jk,jp_sal) = zsp(jk) * tmask(ji,jj,jk)
227               END DO
228               ptsd(ji,jj,jpk,jp_tem) = 0._wp
229               ptsd(ji,jj,jpk,jp_sal) = 0._wp
230            END DO
231         END DO
232         !
[3162]233         CALL wrk_dealloc( jpk, ztp, zsp )
234         !
[3132]235      ELSE                                !==   z- or zps- coordinate   ==!
236         !                             
[7698]237!$OMP PARALLEL DO schedule(static) private(jk, jj, ji)
238         DO jk = 1, jpk
239            DO jj = 1, jpj
240               DO ji = 1, jpi
241                  ptsd(ji,jj,jk,jp_tem) = ptsd(ji,jj,jk,jp_tem) * tmask(ji,jj,jk)    ! Mask
242                  ptsd(ji,jj,jk,jp_sal) = ptsd(ji,jj,jk,jp_sal) * tmask(ji,jj,jk)
243               END DO
244            END DO
245         END DO
[3132]246         !
247         IF( ln_zps ) THEN                      ! zps-coordinate (partial steps) interpolation at the last ocean level
[7698]248!$OMP PARALLEL DO schedule(static) private(jj, ji, ik, zl)
[3132]249            DO jj = 1, jpj
250               DO ji = 1, jpi
251                  ik = mbkt(ji,jj) 
252                  IF( ik > 1 ) THEN
[4292]253                     zl = ( gdept_1d(ik) - gdept_0(ji,jj,ik) ) / ( gdept_1d(ik) - gdept_1d(ik-1) )
[3132]254                     ptsd(ji,jj,ik,jp_tem) = (1.-zl) * ptsd(ji,jj,ik,jp_tem) + zl * ptsd(ji,jj,ik-1,jp_tem)
255                     ptsd(ji,jj,ik,jp_sal) = (1.-zl) * ptsd(ji,jj,ik,jp_sal) + zl * ptsd(ji,jj,ik-1,jp_sal)
256                  ENDIF
[4990]257                  ik = mikt(ji,jj)
258                  IF( ik > 1 ) THEN
259                     zl = ( gdept_0(ji,jj,ik) - gdept_1d(ik) ) / ( gdept_1d(ik+1) - gdept_1d(ik) ) 
260                     ptsd(ji,jj,ik,jp_tem) = (1.-zl) * ptsd(ji,jj,ik,jp_tem) + zl * ptsd(ji,jj,ik+1,jp_tem)
261                     ptsd(ji,jj,ik,jp_sal) = (1.-zl) * ptsd(ji,jj,ik,jp_sal) + zl * ptsd(ji,jj,ik+1,jp_sal)
262                  END IF
[3132]263               END DO
264            END DO
265         ENDIF
266         !
267      ENDIF
268      !
269      IF( .NOT.ln_tsd_tradmp ) THEN                   !==   deallocate T & S structure   ==!
270         !                                              (data used only for initialisation)
271         IF(lwp) WRITE(numout,*) 'dta_tsd: deallocte T & S arrays as they are only use to initialize the run'
272                                        DEALLOCATE( sf_tsd(jp_tem)%fnow )     ! T arrays in the structure
273         IF( sf_tsd(jp_tem)%ln_tint )   DEALLOCATE( sf_tsd(jp_tem)%fdta )
274                                        DEALLOCATE( sf_tsd(jp_sal)%fnow )     ! S arrays in the structure
275         IF( sf_tsd(jp_sal)%ln_tint )   DEALLOCATE( sf_tsd(jp_sal)%fdta )
276                                        DEALLOCATE( sf_tsd              )     ! the structure itself
277      ENDIF
278      !
[3162]279      IF( nn_timing == 1 )  CALL timing_stop('dta_tsd')
280      !
[3132]281   END SUBROUTINE dta_tsd
282
283   !!======================================================================
284END MODULE dtatsd
Note: See TracBrowser for help on using the repository browser.