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.
tide_mod.F90 in NEMO/branches/2019/dev_r10742_ENHANCE-12_SimonM-Tides/src/OCE/TDE – NEMO

source: NEMO/branches/2019/dev_r10742_ENHANCE-12_SimonM-Tides/src/OCE/TDE/tide_mod.F90 @ 12065

Last change on this file since 12065 was 12065, checked in by smueller, 4 years ago

Synchronizing with /NEMO/trunk@12055 (ticket #2194)

  • Property svn:keywords set to Id
File size: 35.8 KB
Line 
1MODULE tide_mod
2   !!======================================================================
3   !!                       ***  MODULE  tide_mod  ***
4   !! Compute nodal modulations corrections and pulsations
5   !!======================================================================
6   !! History :  1.0  !  2007  (O. Le Galloudec)  Original code
7   !!                 !  2019  (S. Mueller)
8   !!----------------------------------------------------------------------
9   !!
10   !! ** Reference :
11   !!       S58) Schureman, P. (1958): Manual of Harmonic Analysis and
12   !!            Prediction of Tides (Revised (1940) Edition (Reprinted 1958
13   !!            with corrections). Reprinted June 2001). U.S. Department of
14   !!            Commerce, Coast and Geodetic Survey Special Publication
15   !!            No. 98. Washington DC, United States Government Printing
16   !!            Office. 317 pp. DOI: 10.25607/OBP-155.
17   !!----------------------------------------------------------------------
18
19   USE oce, ONLY : sshn       ! sea-surface height
20   USE par_oce                ! ocean parameters
21   USE phycst, ONLY : rpi     ! pi
22   USE daymod, ONLY : ndt05   ! half-length of time step
23   USE in_out_manager         ! I/O units
24   USE iom                    ! xIOs server
25
26   IMPLICIT NONE
27   PRIVATE
28
29   PUBLIC   tide_init
30   PUBLIC   tide_update           ! called by stp
31   PUBLIC   tide_init_harmonics   ! called internally and by module diaharm
32   PUBLIC   upd_tide              ! called in dynspg_... modules
33
34   INTEGER, PUBLIC, PARAMETER ::   jpmax_harmo = 64   !: maximum number of harmonic components
35
36   TYPE ::    tide
37      CHARACTER(LEN=4) ::   cname_tide = ''
38      REAL(wp)         ::   equitide
39      INTEGER          ::   nt, ns, nh, np, np1, shift
40      INTEGER          ::   nksi, nnu0, nnu1, nnu2, R
41      INTEGER          ::   nformula
42   END TYPE tide
43
44   TYPE(tide), DIMENSION(:), POINTER ::   tide_components   !: Array of selected tidal component parameters
45
46   TYPE, PUBLIC ::   tide_harmonic       !:   Oscillation parameters of harmonic tidal components
47      CHARACTER(LEN=4) ::   cname_tide   !    Name of component
48      REAL(wp)         ::   equitide     !    Amplitude of equilibrium tide
49      REAL(wp)         ::   f            !    Node factor
50      REAL(wp)         ::   omega        !    Angular velocity
51      REAL(wp)         ::   v0           !    Initial phase at prime meridian
52      REAL(wp)         ::   u            !    Phase correction
53   END type tide_harmonic
54
55   TYPE(tide_harmonic), PUBLIC, DIMENSION(:), POINTER ::   tide_harmonics   !: Oscillation parameters of selected tidal components
56
57   LOGICAL , PUBLIC ::   ln_tide             !:
58   LOGICAL , PUBLIC ::   ln_tide_pot         !:
59   INTEGER          ::   nn_tide_var         !  Variant of tidal parameter set and tide-potential computation
60   LOGICAL          ::   ln_tide_dia         !  Enable tidal diagnostic output
61   LOGICAL          ::   ln_read_load        !:
62   LOGICAL , PUBLIC ::   ln_scal_load        !:
63   LOGICAL , PUBLIC ::   ln_tide_ramp        !:
64   INTEGER , PUBLIC ::   nb_harmo            !: Number of active tidal components
65   REAL(wp), PUBLIC ::   rn_tide_ramp_dt     !:
66   REAL(wp), PUBLIC ::   rn_scal_load        !:
67   CHARACTER(lc), PUBLIC ::   cn_tide_load   !:
68   REAL(wp)         ::   rn_tide_gamma       ! Tidal tilt factor
69
70   REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:)   ::   pot_astro            !: tidal potential
71   REAL(wp),         ALLOCATABLE, DIMENSION(:,:)   ::   pot_astro_comp       !  tidal-potential component
72   REAL(wp),         ALLOCATABLE, DIMENSION(:,:,:) ::   amp_pot, phi_pot
73   REAL(wp),         ALLOCATABLE, DIMENSION(:,:,:) ::   amp_load, phi_load
74
75   REAL(wp) ::   rn_tide_ramp_t   !   Elapsed time in seconds
76
77   REAL(wp) ::   sh_T, sh_s, sh_h, sh_p, sh_p1             ! astronomic angles
78   REAL(wp) ::   sh_xi, sh_nu, sh_nuprim, sh_nusec, sh_R   !
79   REAL(wp) ::   sh_I, sh_x1ra, sh_N                       !
80
81   ! Longitudes on 1 Jan 1900, 00h and angular velocities (units of deg and
82   ! deg/h, respectively. The values of these module variables have been copied
83   ! from subroutine astronomic_angle of the version of this module used in
84   ! release version 4.0 of NEMO.
85   REAL(wp) ::   rlon00_N  =  259.1560564_wp               ! Longitude of ascending lunar node
86   REAL(wp) ::   romega_N  = -.0022064139_wp
87   REAL(wp) ::   rlon00_T  =  180.0_wp                     ! Mean solar angle (GMT)
88   REAL(wp) ::   romega_T  =  15.0_wp
89   REAL(wp) ::   rlon00_h  =  280.1895014_wp               ! Mean solar Longitude
90   REAL(wp) ::   romega_h  =  .0410686387_wp
91   REAL(wp) ::   rlon00_s  =  277.0256206_wp               ! Mean lunar Longitude
92   REAL(wp) ::   romega_s  =  .549016532_wp
93   REAL(wp) ::   rlon00_p1 =  281.2208569_wp               ! Longitude of solar perigee
94   REAL(wp) ::   romega_p1 =  .000001961_wp
95   REAL(wp) ::   rlon00_p  =  334.3837214_wp               ! Longitude of lunar perigee
96   REAL(wp) ::   romega_p  =  .004641834_wp
97   ! Values of cos(i)*cos(epsilon), rcice, and sin(incl)*sin(epsilon), rsise,
98   ! where i is the inclination of the orbit of the Moon w.r.t. the ecliptic and
99   ! epsilon the obliquity of the ecliptic on 1 January 1900, 00h. The values of
100   ! these module variables have been copied from subroutine astronomic_angle
101   ! (computation of the cosine of inclination of orbit of Moon to the celestial
102   ! equator) of the version of this module used in release version 4.0 of NEMO.
103   REAL(wp) ::   rcice    = 0.913694997_wp
104   REAL(wp) ::   rsise    = 0.035692561_wp
105   ! Coefficients used to compute sh_xi and sh_nu in subroutine astronomic_angle
106   ! according to two equations given in the explanation of Table 6 of S58
107   REAL(wp) ::   rxinu1, rxinu2
108
109   !!----------------------------------------------------------------------
110   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
111   !! $Id$
112   !! Software governed by the CeCILL license (see ./LICENSE)
113   !!----------------------------------------------------------------------
114CONTAINS
115
116   SUBROUTINE tide_init
117      !!----------------------------------------------------------------------
118      !!                 ***  ROUTINE tide_init  ***
119      !!----------------------------------------------------------------------     
120      INTEGER  :: ji, jk
121      CHARACTER(LEN=4), DIMENSION(jpmax_harmo) :: sn_tide_cnames ! Names of selected tidal components
122      INTEGER  ::   ios                 ! Local integer output status for namelist read
123      !
124      NAMELIST/nam_tide/ln_tide, nn_tide_var, ln_tide_dia, ln_tide_pot, rn_tide_gamma, &
125         &              ln_scal_load, ln_read_load, cn_tide_load,         &
126         &              ln_tide_ramp, rn_scal_load, rn_tide_ramp_dt,      &
127         &              sn_tide_cnames
128      !!----------------------------------------------------------------------
129      !
130      ! Initialise all array elements of sn_tide_cnames, as some of them
131      ! typically do not appear in namelist_ref or namelist_cfg
132      sn_tide_cnames(:) = ''
133      ! Read Namelist nam_tide
134      REWIND( numnam_ref )              ! Namelist nam_tide in reference namelist : Tides
135      READ  ( numnam_ref, nam_tide, IOSTAT = ios, ERR = 901)
136901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'nam_tide in reference namelist' )
137      !
138      REWIND( numnam_cfg )              ! Namelist nam_tide in configuration namelist : Tides
139      READ  ( numnam_cfg, nam_tide, IOSTAT = ios, ERR = 902 )
140902   IF( ios >  0 )   CALL ctl_nam ( ios , 'nam_tide in configuration namelist' )
141      IF(lwm) WRITE ( numond, nam_tide )
142      !
143      IF( ln_tide ) THEN
144         IF (lwp) THEN
145            WRITE(numout,*)
146            WRITE(numout,*) 'tide_init : Initialization of the tidal components'
147            WRITE(numout,*) '~~~~~~~~~ '
148            WRITE(numout,*) '   Namelist nam_tide'
149            WRITE(numout,*) '      Use tidal components                       ln_tide         = ', ln_tide
150            WRITE(numout,*) '         Variant (1: default; 0: legacy option)  nn_tide_var     = ', nn_tide_var
151            WRITE(numout,*) '         Tidal diagnostic output                 ln_tide_dia     = ', ln_tide_dia
152            WRITE(numout,*) '         Apply astronomical potential            ln_tide_pot     = ', ln_tide_pot
153            WRITE(numout,*) '         Tidal tilt factor                       rn_tide_gamma   = ', rn_tide_gamma
154            WRITE(numout,*) '         Use scalar approx. for load potential   ln_scal_load    = ', ln_scal_load
155            WRITE(numout,*) '         Read load potential from file           ln_read_load    = ', ln_read_load
156            WRITE(numout,*) '         Apply ramp on tides at startup          ln_tide_ramp    = ', ln_tide_ramp
157            WRITE(numout,*) '         Fraction of SSH used in scal. approx.   rn_scal_load    = ', rn_scal_load
158            WRITE(numout,*) '         Duration (days) of ramp                 rn_tide_ramp_dt = ', rn_tide_ramp_dt
159         ENDIF
160      ELSE
161         rn_scal_load = 0._wp 
162
163         IF(lwp) WRITE(numout,*)
164         IF(lwp) WRITE(numout,*) 'tide_init : tidal components not used (ln_tide = F)'
165         IF(lwp) WRITE(numout,*) '~~~~~~~~~ '
166         RETURN
167      ENDIF
168      !
169      IF( ln_read_load.AND.(.NOT.ln_tide_pot) ) &
170          &   CALL ctl_stop('ln_read_load requires ln_tide_pot')
171      IF( ln_scal_load.AND.(.NOT.ln_tide_pot) ) &
172          &   CALL ctl_stop('ln_scal_load requires ln_tide_pot')
173      IF( ln_scal_load.AND.ln_read_load ) &
174          &   CALL ctl_stop('Choose between ln_scal_load and ln_read_load')
175      IF( ln_tide_ramp.AND.((nitend-nit000+1)*rdt/rday < rn_tide_ramp_dt) )   &
176         &   CALL ctl_stop('rn_tide_ramp_dt must be lower than run duration')
177      IF( ln_tide_ramp.AND.(rn_tide_ramp_dt<0.) ) &
178         &   CALL ctl_stop('rn_tide_ramp_dt must be positive')
179      !
180      ! Compute coefficients which are used in subroutine astronomic_angle to
181      ! compute sh_xi and sh_nu according to two equations given in the
182      ! explanation of Table 6 of S58
183      rxinu1 = COS( 0.5_wp * ( ABS( ACOS( rcice + rsise ) ) ) ) / COS( 0.5_wp * ( ACOS( rcice - rsise ) ) )
184      rxinu2 = SIN( 0.5_wp * ( ABS( ACOS( rcice + rsise ) ) ) ) / SIN( 0.5_wp * ( ACOS( rcice - rsise ) ) )
185      !
186      ! Initialise array used to store tidal oscillation parameters (frequency,
187      ! amplitude, phase); also retrieve and store array of information about
188      ! selected tidal components
189      CALL tide_init_harmonics(sn_tide_cnames, tide_harmonics, tide_components)
190      !
191      ! Number of active tidal components
192      nb_harmo = size(tide_components)
193      !       
194      ! Ensure that tidal components have been set in namelist_cfg
195      IF( nb_harmo == 0 )   CALL ctl_stop( 'tide_init : No tidal components set in nam_tide' )
196      !
197      IF (.NOT.ln_scal_load ) rn_scal_load = 0._wp
198      !
199      ALLOCATE( amp_pot(jpi,jpj,nb_harmo),                      &
200           &      phi_pot(jpi,jpj,nb_harmo), pot_astro(jpi,jpj)   )
201      IF( ln_tide_dia ) ALLOCATE( pot_astro_comp(jpi,jpj) )
202      IF( ln_read_load ) THEN
203         ALLOCATE( amp_load(jpi,jpj,nb_harmo), phi_load(jpi,jpj,nb_harmo) )
204         CALL tide_init_load
205         amp_pot(:,:,:) = amp_load(:,:,:)
206         phi_pot(:,:,:) = phi_load(:,:,:)
207      ELSE     
208         amp_pot(:,:,:) = 0._wp
209         phi_pot(:,:,:) = 0._wp   
210      ENDIF
211      !
212   END SUBROUTINE tide_init
213
214
215   SUBROUTINE tide_init_components(pcnames, ptide_comp)
216      !!----------------------------------------------------------------------
217      !!                 ***  ROUTINE tide_init_components  ***
218      !!
219      !! Returns pointer to array of variables of type 'tide' that contain
220      !! information about the selected tidal components
221      !! ----------------------------------------------------------------------
222      CHARACTER(LEN=4),              DIMENSION(jpmax_harmo), INTENT(in)  ::   pcnames             ! Names of selected components
223      TYPE(tide),       POINTER,     DIMENSION(:),           INTENT(out) ::   ptide_comp          ! Selected components
224      INTEGER,          ALLOCATABLE, DIMENSION(:)                        ::   icomppos            ! Indices of selected components
225      INTEGER                                                            ::   icomp, jk, jj, ji   ! Miscellaneous integers
226      LOGICAL                                                            ::   llmatch             ! Local variables used for
227      INTEGER                                                            ::   ic1, ic2            !    string comparison
228      TYPE(tide),       POINTER,     DIMENSION(:)                        ::   tide_components     ! All available components
229     
230      ! Populate local array with information about all available tidal
231      ! components
232      !
233      ! Note, here 'tide_components' locally overrides the global module
234      ! variable of the same name to enable the use of the global name in the
235      ! include file that contains the initialisation of elements of array
236      ! 'tide_components'
237      ALLOCATE(tide_components(jpmax_harmo), icomppos(jpmax_harmo))
238      ! Initialise array of indices of the selected componenents
239      icomppos(:) = 0
240      ! Include tidal component parameters for all available components
241      IF (nn_tide_var < 1) THEN
242#define TIDE_VAR_0
243#include "tide.h90"
244#undef TIDE_VAR_0
245      ELSE
246#include "tide.h90"
247      END IF
248      ! Identify the selected components that are availble
249      icomp = 0
250      DO jk = 1, jpmax_harmo
251         IF (TRIM(pcnames(jk)) /= '') THEN
252            DO jj = 1, jpmax_harmo
253               ! Find matches between selected and available constituents
254               ! (ignore capitalisation unless legacy variant has been selected)
255               IF (nn_tide_var < 1) THEN
256                  llmatch = (TRIM(pcnames(jk)) == TRIM(tide_components(jj)%cname_tide))
257               ELSE
258                  llmatch = .TRUE.
259                  ji = MAX(LEN_TRIM(pcnames(jk)), LEN_TRIM(tide_components(jj)%cname_tide))
260                  DO WHILE (llmatch.AND.(ji > 0))
261                     ic1 = IACHAR(pcnames(jk)(ji:ji))
262                     IF ((ic1 >= 97).AND.(ic1 <= 122)) ic1 = ic1 - 32
263                     ic2 = IACHAR(tide_components(jj)%cname_tide(ji:ji))
264                     IF ((ic2 >= 97).AND.(ic2 <= 122)) ic2 = ic2 - 32
265                     llmatch = (ic1 == ic2)
266                     ji = ji - 1
267                  END DO
268               END IF
269               IF (llmatch) THEN
270                  ! Count and record the match
271                  icomp = icomp + 1
272                  icomppos(icomp) = jj
273                  ! Set the capitalisation of the tidal constituent identifier
274                  ! as specified in the namelist
275                  tide_components(jj)%cname_tide = pcnames(jk)
276                  IF (lwp) WRITE(numout, '(10X,"Tidal component #",I2.2,36X,"= ",A4)') icomp, tide_components(jj)%cname_tide
277                  EXIT
278               END IF
279            END DO
280            IF ((lwp).AND.(jj > jpmax_harmo)) WRITE(numout, '(10X,"Tidal component ",A4," is not available!")') pcnames(jk)
281         END IF
282      END DO
283     
284      ! Allocate and populate reduced list of components
285      ALLOCATE(ptide_comp(icomp))
286      DO jk = 1, icomp
287         ptide_comp(jk) = tide_components(icomppos(jk))
288      END DO
289     
290      ! Release local array of available components and list of selected
291      ! components
292      DEALLOCATE(tide_components, icomppos)
293     
294   END SUBROUTINE tide_init_components
295
296
297   SUBROUTINE tide_init_harmonics(pcnames, ptide_harmo, ptide_comp)
298      !!----------------------------------------------------------------------
299      !!                 ***  ROUTINE tide_init_harmonics  ***
300      !!
301      !! Returns pointer to array of variables of type 'tide_harmonics' that
302      !! contain oscillation parameters of the selected harmonic tidal
303      !! components
304      !! ----------------------------------------------------------------------
305      CHARACTER(LEN=4),             DIMENSION(jpmax_harmo), INTENT(in) ::   pcnames     ! Names of selected components
306      TYPE(tide_harmonic), POINTER, DIMENSION(:)                       ::   ptide_harmo ! Oscillation parameters of tidal components
307      TYPE(tide),          POINTER, DIMENSION(:), OPTIONAL             ::   ptide_comp  ! Selected components
308      TYPE(tide),          POINTER, DIMENSION(:)                       ::   ztcomp      ! Selected components
309
310      ! Retrieve information about selected tidal components
311      ! If requested, prepare tidal component array for returning
312      IF (PRESENT(ptide_comp)) THEN
313         CALL tide_init_components(pcnames, ptide_comp)
314         ztcomp => ptide_comp
315      ELSE
316         CALL tide_init_components(pcnames, ztcomp)
317      END IF
318
319      ! Allocate and populate array of oscillation parameters
320      ALLOCATE(ptide_harmo(size(ztcomp)))
321      ptide_harmo(:)%cname_tide = ztcomp(:)%cname_tide
322      ptide_harmo(:)%equitide = ztcomp(:)%equitide
323      CALL tide_harmo(ztcomp, ptide_harmo)
324
325   END SUBROUTINE tide_init_harmonics
326
327
328   SUBROUTINE tide_init_potential
329      !!----------------------------------------------------------------------
330      !!                 ***  ROUTINE tide_init_potential  ***
331      !!
332      !! ** Reference :
333      !!      CT71) Cartwright, D. E. and Tayler, R. J. (1971): New computations of
334      !!            the Tide-generating Potential. Geophys. J. R. astr. Soc. 23,
335      !!            pp. 45-74. DOI: 10.1111/j.1365-246X.1971.tb01803.x
336      !!
337      !!----------------------------------------------------------------------
338      INTEGER  ::   ji, jj, jk   ! dummy loop indices
339      REAL(wp) ::   zcons, ztmp1, ztmp2, zlat, zlon, ztmp, zamp, zcs   ! local scalar
340      !!----------------------------------------------------------------------
341
342      IF( ln_read_load ) THEN
343    amp_pot(:,:,:) = amp_load(:,:,:)
344    phi_pot(:,:,:) = phi_load(:,:,:)
345      ELSE     
346         amp_pot(:,:,:) = 0._wp
347         phi_pot(:,:,:) = 0._wp   
348      ENDIF
349      DO jk = 1, nb_harmo
350         zcons = rn_tide_gamma * tide_components(jk)%equitide * tide_harmonics(jk)%f
351         DO ji = 1, jpi
352            DO jj = 1, jpj
353               ztmp1 =  tide_harmonics(jk)%f * amp_pot(ji,jj,jk) * COS( phi_pot(ji,jj,jk) &
354                  &                                                   + tide_harmonics(jk)%v0 + tide_harmonics(jk)%u )
355               ztmp2 = -tide_harmonics(jk)%f * amp_pot(ji,jj,jk) * SIN( phi_pot(ji,jj,jk) &
356                  &                                                   + tide_harmonics(jk)%v0 + tide_harmonics(jk)%u )
357               zlat = gphit(ji,jj)*rad !! latitude en radian
358               zlon = glamt(ji,jj)*rad !! longitude en radian
359               ztmp = tide_harmonics(jk)%v0 + tide_harmonics(jk)%u + tide_components(jk)%nt * zlon
360               ! le potentiel est composé des effets des astres:
361               SELECT CASE( tide_components(jk)%nt )
362               CASE( 0 )                                                  !   long-periodic tidal constituents (included unless
363                  zcs = zcons * ( 0.5_wp - 1.5_wp * SIN( zlat )**2 )      !   compatibility with original formulation is requested)
364                  IF ( nn_tide_var < 1 ) zcs = 0.0_wp
365               CASE( 1 )                                                  !   diurnal tidal constituents
366                  zcs = zcons * SIN( 2.0_wp*zlat )
367               CASE( 2 )                                                  !   semi-diurnal tidal constituents
368                  zcs = zcons * COS( zlat )**2
369               CASE( 3 )                                                  !   Terdiurnal tidal constituents; the colatitude-dependent
370                  zcs = zcons * COS( zlat )**3                            !   factor is sin(theta)^3 (Table 2 of CT71)
371               CASE DEFAULT                                               !   constituents of higher frequency are not included
372                  zcs = 0.0_wp
373               END SELECT
374               ztmp1 = ztmp1 + zcs * COS( ztmp )
375               ztmp2 = ztmp2 - zcs * SIN( ztmp )
376               zamp = SQRT( ztmp1*ztmp1 + ztmp2*ztmp2 )
377               amp_pot(ji,jj,jk) = zamp
378               phi_pot(ji,jj,jk) = ATAN2( -ztmp2 / MAX( 1.e-10_wp , zamp ) ,   &
379                  &                        ztmp1 / MAX( 1.e-10_wp,  zamp )   )
380            END DO
381         END DO
382      END DO
383      !
384   END SUBROUTINE tide_init_potential
385
386
387   SUBROUTINE tide_init_load
388      !!----------------------------------------------------------------------
389      !!                 ***  ROUTINE tide_init_load  ***
390      !!----------------------------------------------------------------------
391      INTEGER :: inum                 ! Logical unit of input file
392      INTEGER :: ji, jj, itide        ! dummy loop indices
393      REAL(wp), DIMENSION(jpi,jpj) ::   ztr, zti   !: workspace to read in tidal harmonics data
394      !!----------------------------------------------------------------------
395      IF(lwp) THEN
396         WRITE(numout,*)
397         WRITE(numout,*) 'tide_init_load : Initialization of load potential from file'
398         WRITE(numout,*) '~~~~~~~~~~~~~~ '
399      ENDIF
400      !
401      CALL iom_open ( cn_tide_load , inum )
402      !
403      DO itide = 1, nb_harmo
404         CALL iom_get  ( inum, jpdom_data,TRIM(tide_components(itide)%cname_tide)//'_z1', ztr(:,:) )
405         CALL iom_get  ( inum, jpdom_data,TRIM(tide_components(itide)%cname_tide)//'_z2', zti(:,:) )
406         !
407         DO ji=1,jpi
408            DO jj=1,jpj
409               amp_load(ji,jj,itide) =  SQRT( ztr(ji,jj)**2. + zti(ji,jj)**2. )
410               phi_load(ji,jj,itide) = ATAN2(-zti(ji,jj), ztr(ji,jj) )
411            END DO
412         END DO
413         !
414      END DO
415      CALL iom_close( inum )
416      !
417   END SUBROUTINE tide_init_load
418
419
420   SUBROUTINE tide_update( kt )
421      !!----------------------------------------------------------------------
422      !!                 ***  ROUTINE tide_update  ***
423      !!----------------------------------------------------------------------     
424      INTEGER, INTENT( in ) ::   kt     ! ocean time-step
425      INTEGER               ::   jk     ! dummy loop index
426      !!----------------------------------------------------------------------
427     
428      IF( nsec_day == NINT(0.5_wp * rdt) .OR. kt == nit000 ) THEN      ! start a new day
429         !
430         CALL tide_harmo(tide_components, tide_harmonics, ndt05) ! Update oscillation parameters of tidal components for start of current day
431         !
432         !
433         IF(lwp) THEN
434            WRITE(numout,*)
435            WRITE(numout,*) 'tide_update : Update of the components and (re)Init. the potential at kt=', kt
436            WRITE(numout,*) '~~~~~~~~~~~ '
437            DO jk = 1, nb_harmo
438               WRITE(numout,*) tide_harmonics(jk)%cname_tide, tide_harmonics(jk)%u, &
439                  &            tide_harmonics(jk)%f,tide_harmonics(jk)%v0, tide_harmonics(jk)%omega
440            END DO
441         ENDIF
442         !
443         IF( ln_tide_pot )   CALL tide_init_potential
444         !
445         rn_tide_ramp_t = (kt - nit000)*rdt !   Elapsed time in seconds
446      ENDIF
447      !
448   END SUBROUTINE tide_update
449
450
451   SUBROUTINE tide_harmo( ptide_comp, ptide_harmo, psec_day )
452      !
453      TYPE(tide),          DIMENSION(:), POINTER ::   ptide_comp   ! Array of selected tidal component parameters
454      TYPE(tide_harmonic), DIMENSION(:), POINTER ::   ptide_harmo  ! Oscillation parameters of selected tidal components
455      INTEGER, OPTIONAL ::   psec_day                              ! Number of seconds since the start of the current day
456      !
457      IF (PRESENT(psec_day)) THEN
458         CALL astronomic_angle(psec_day)
459      ELSE
460         CALL astronomic_angle(nsec_day)
461      END IF
462      CALL tide_pulse( ptide_comp, ptide_harmo )
463      CALL tide_vuf(   ptide_comp, ptide_harmo )
464      !
465   END SUBROUTINE tide_harmo
466
467
468   SUBROUTINE astronomic_angle(psec_day)
469      !!----------------------------------------------------------------------
470      !!                 ***  ROUTINE astronomic_angle  ***
471      !!                     
472      !! ** Purpose : Compute astronomic angles
473      !!----------------------------------------------------------------------
474      INTEGER  ::   psec_day !   Number of seconds from midnight
475      REAL(wp) ::   zp, zq, zt2, zs2, ztgI2, zP1, ztgn2, zat1, zat2
476      REAL(wp) ::   zqy , zsy, zday, zdj, zhfrac, zt
477      !!----------------------------------------------------------------------
478      !
479      ! Computation of the time from 1 Jan 1900, 00h in years
480      zqy = AINT( (nyear - 1901.0_wp) / 4.0_wp )
481      zsy = nyear - 1900.0_wp
482      !
483      zdj  = dayjul( nyear, nmonth, nday )
484      zday = zdj + zqy - 1.0_wp
485      !
486      zhfrac = psec_day / 3600.0_wp
487      !
488      zt = zsy * 365.0_wp * 24.0_wp + zday * 24.0_wp + zhfrac
489      !
490      ! Longitude of ascending lunar node
491      sh_N  = ( rlon00_N  + romega_N * zt     ) * rad
492      sh_N = MOD( sh_N,  2*rpi )
493      ! Mean solar angle (Greenwhich time)
494      sh_T  = ( rlon00_T  + romega_T * zhfrac ) * rad
495      ! Mean solar Longitude
496      sh_h  = ( rlon00_h  + romega_h * zt     ) * rad
497      sh_h = MOD( sh_h,  2*rpi )
498      ! Mean lunar Longitude
499      sh_s  = ( rlon00_s  + romega_s * zt     ) * rad
500      sh_s = MOD( sh_s,  2*rpi )
501      ! Longitude of solar perigee
502      sh_p1 = ( rlon00_p1 + romega_p1 * zt    ) * rad
503      sh_p1= MOD( sh_p1, 2*rpi )
504      ! Longitude of lunar perigee
505      sh_p  = ( rlon00_p  + romega_p  * zt    ) * rad
506      sh_p = MOD( sh_p,  2*rpi )
507      !
508      ! Inclination of the orbit of the moon w.r.t. the celestial equator, see
509      ! explanation of Table 6 of S58
510      sh_I = ACOS( rcice - rsise * COS( sh_N ) )
511      !
512      ! Computation of sh_xi and sh_nu, see explanation of Table 6 of S58
513      ztgn2 = TAN( sh_N / 2.0_wp )
514      zat1 = ATAN( rxinu1 * ztgn2 )
515      zat2 = ATAN( rxinu2 * ztgn2 )
516      sh_xi = sh_N - zat1 - zat2
517      IF( sh_N > rpi ) sh_xi = sh_xi - 2.0_wp * rpi
518      sh_nu = zat1 - zat2
519      !
520      ! Computation of sh_x1ra, sh_R, sh_nuprim, and sh_nusec used for tidal
521      ! constituents L2, K1, and K2
522      !
523      ! Computation of sh_x1ra and sh_R (Equations 204, 213, and 214 of S58)
524      ztgI2 = tan( sh_I / 2.0_wp )
525      zP1   = sh_p - sh_xi
526      zt2   = ztgI2 * ztgI2
527      sh_x1ra = SQRT( 1.0 - 12.0 * zt2 * COS( 2.0_wp * zP1 ) + 36.0_wp * zt2 * zt2 )
528      zp = SIN( 2.0_wp * zP1 )
529      zq = 1.0_wp / ( 6.0_wp * zt2 ) - COS( 2.0_wp * zP1 )
530      sh_R = ATAN( zp / zq )
531      !
532      ! Computation of sh_nuprim (Equation 224 of S58)
533      zp = SIN( 2.0_wp * sh_I ) * SIN( sh_nu )
534      zq = SIN( 2.0_wp * sh_I ) * COS( sh_nu ) + 0.3347_wp
535      sh_nuprim = ATAN( zp / zq )
536      !
537      ! Computation of sh_nusec  (Equation 232 of S58)
538      zs2 = SIN( sh_I ) * SIN( sh_I )
539      zp  = zs2 * SIN( 2.0_wp * sh_nu )
540      zq  = zs2 * COS( 2.0_wp * sh_nu ) + 0.0727_wp
541      sh_nusec = 0.5_wp * ATAN( zp / zq )
542      !
543   END SUBROUTINE astronomic_angle
544
545
546   SUBROUTINE tide_pulse( ptide_comp, ptide_harmo )
547      !!----------------------------------------------------------------------
548      !!                     ***  ROUTINE tide_pulse  ***
549      !!                     
550      !! ** Purpose : Compute tidal frequencies
551      !!----------------------------------------------------------------------
552      TYPE(tide),          DIMENSION(:), POINTER ::   ptide_comp   ! Array of selected tidal component parameters
553      TYPE(tide_harmonic), DIMENSION(:), POINTER ::   ptide_harmo  ! Oscillation parameters of selected tidal components
554      !
555      INTEGER  ::   jh
556      REAL(wp) ::   zscale
557      !!----------------------------------------------------------------------
558      !
559      zscale =  rad / 3600.0_wp
560      !
561      DO jh = 1, size(ptide_harmo)
562         ptide_harmo(jh)%omega = (  romega_T * ptide_comp( jh )%nT   &
563            &                     + romega_s * ptide_comp( jh )%ns   &
564            &                     + romega_h * ptide_comp( jh )%nh   &
565            &                     + romega_p * ptide_comp( jh )%np   &
566            &                     + romega_p1* ptide_comp( jh )%np1  ) * zscale
567      END DO
568      !
569   END SUBROUTINE tide_pulse
570
571
572   SUBROUTINE tide_vuf( ptide_comp, ptide_harmo )
573      !!----------------------------------------------------------------------
574      !!                     ***  ROUTINE tide_vuf  ***
575      !!                     
576      !! ** Purpose : Compute nodal modulation corrections
577      !!
578      !! ** Outputs : vt: Phase of tidal potential relative to Greenwich (radians)
579      !!              ut: Phase correction u due to nodal motion (radians)
580      !!              ft: Nodal correction factor
581      !!----------------------------------------------------------------------
582      TYPE(tide),          DIMENSION(:), POINTER ::   ptide_comp   ! Array of selected tidal component parameters
583      TYPE(tide_harmonic), DIMENSION(:), POINTER ::   ptide_harmo  ! Oscillation parameters of selected tidal components
584      !
585      INTEGER ::   jh   ! dummy loop index
586      !!----------------------------------------------------------------------
587      !
588      DO jh = 1, size(ptide_harmo)
589         !  Phase of the tidal potential relative to the Greenwhich
590         !  meridian (e.g. the position of the fictuous celestial body). Units are radian:
591         ptide_harmo(jh)%v0 = sh_T * ptide_comp( jh )%nT    &
592            &                   + sh_s * ptide_comp( jh )%ns    &
593            &                   + sh_h * ptide_comp( jh )%nh    &
594            &                   + sh_p * ptide_comp( jh )%np    &
595            &                   + sh_p1* ptide_comp( jh )%np1   &
596            &                   +        ptide_comp( jh )%shift * rad
597         !
598         !  Phase correction u due to nodal motion. Units are radian:
599         ptide_harmo(jh)%u = sh_xi     * ptide_comp( jh )%nksi   &
600            &                  + sh_nu     * ptide_comp( jh )%nnu0   &
601            &                  + sh_nuprim * ptide_comp( jh )%nnu1   &
602            &                  + sh_nusec  * ptide_comp( jh )%nnu2   &
603            &                  + sh_R      * ptide_comp( jh )%R
604
605         !  Nodal correction factor:
606         ptide_harmo(jh)%f = nodal_factort( ptide_comp( jh )%nformula )
607      END DO
608      !
609   END SUBROUTINE tide_vuf
610
611
612   RECURSIVE FUNCTION nodal_factort( kformula ) RESULT( zf )
613      !!----------------------------------------------------------------------
614      !!                  ***  FUNCTION nodal_factort  ***
615      !!
616      !! ** Purpose : Compute amplitude correction factors due to nodal motion
617      !!----------------------------------------------------------------------
618      INTEGER, INTENT(in) ::   kformula
619      !
620      REAL(wp)            ::   zf
621      REAL(wp)            ::   zs, zf1, zf2
622      CHARACTER(LEN=3)    ::   clformula
623      !!----------------------------------------------------------------------
624      !
625      SELECT CASE( kformula )
626      !
627      CASE( 0 )                  ! Formula 0, solar waves
628         zf = 1.0
629         !
630      CASE( 1 )                  ! Formula 1, compound waves (78 x 78)
631         zf=nodal_factort( 78 )
632         zf = zf * zf
633         !
634      CASE ( 4 )                 ! Formula 4,  compound waves (78 x 235)
635         zf1 = nodal_factort( 78 )
636         zf  = nodal_factort(235)
637         zf  = zf1 * zf
638         !
639      CASE( 18 )                 ! Formula 18,  compound waves (78 x 78 x 78 )
640         zf1 = nodal_factort( 78 )
641         zf  = zf1 * zf1 * zf1
642         !
643      CASE( 20 )                 ! Formula 20, compound waves ( 78 x 78 x 78 x 78 )
644         zf1 = nodal_factort( 78 )
645         zf  = zf1 * zf1 * zf1 * zf1
646         !
647      CASE( 73 )                 ! Formula 73 of S58
648         zs = SIN( sh_I )
649         zf = ( 2.0_wp / 3.0_wp - zs * zs ) / 0.5021_wp
650         !
651      CASE( 74 )                 ! Formula 74 of S58
652         zs = SIN(sh_I)
653         zf = zs * zs / 0.1578_wp
654         !
655      CASE( 75 )                 ! Formula 75 of S58
656         zs = COS( sh_I / 2.0_wp )
657         zf = SIN( sh_I ) * zs * zs / 0.3800_wp
658         !
659      CASE( 76 )                 ! Formula 76 of S58
660         zf = SIN( 2.0_wp * sh_I ) / 0.7214_wp
661         !
662      CASE( 78 )                 ! Formula 78 of S58
663         zs = COS( sh_I/2 )
664         zf = zs * zs * zs * zs / 0.9154_wp
665         !
666      CASE( 149 )                ! Formula 149 of S58
667         zs = COS( sh_I/2 )
668         zf = zs * zs * zs * zs * zs * zs / 0.8758_wp
669         !
670      CASE( 215 )                ! Formula 215 of S58 with typo correction (0.9154 instead of 0.9145)
671         zs = COS( sh_I/2 )
672         zf = zs * zs * zs * zs / 0.9154_wp * sh_x1ra
673         !
674      CASE( 227 )                ! Formula 227 of S58
675         zs = SIN( 2.0_wp * sh_I )
676         zf = SQRT( 0.8965_wp * zs * zs + 0.6001_wp * zs * COS( sh_nu ) + 0.1006_wp )
677         !
678      CASE ( 235 )               ! Formula 235 of S58
679         zs = SIN( sh_I )
680         zf = SQRT( 19.0444_wp * zs * zs * zs * zs + 2.7702_wp * zs * zs * cos( 2.0_wp * sh_nu ) + 0.0981_wp )
681         !
682      CASE DEFAULT
683         WRITE( clformula, '(I3)' ) kformula
684         CALL ctl_stop('nodal_factort: formula ' // clformula // ' is not available')
685      END SELECT
686      !
687   END FUNCTION nodal_factort
688
689
690   FUNCTION dayjul( kyr, kmonth, kday )
691      !!----------------------------------------------------------------------
692      !!                   ***  FUNCTION dayjul  ***
693      !!
694      !! Purpose :  compute the Julian day
695      !!----------------------------------------------------------------------
696      INTEGER,INTENT(in)    ::   kyr, kmonth, kday
697      !
698      INTEGER,DIMENSION(12) ::   idayt = (/ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 /)
699      INTEGER,DIMENSION(12) ::   idays
700      INTEGER               ::   inc, ji, zyq
701      REAL(wp)              ::   dayjul
702      !!----------------------------------------------------------------------
703      !
704      idays(1) = 0
705      idays(2) = 31
706      inc = 0.0_wp
707      zyq = MOD( kyr - 1900 , 4 )
708      IF( zyq == 0 ) inc = 1
709      DO ji = 3, 12
710         idays(ji) = idayt(ji) + inc
711      END DO
712      dayjul = REAL( idays(kmonth) + kday, KIND=wp )
713      !
714   END FUNCTION dayjul
715
716
717   SUBROUTINE upd_tide(pdelta)
718      !!----------------------------------------------------------------------
719      !!                 ***  ROUTINE upd_tide  ***
720      !!
721      !! ** Purpose :   provide at each time step the astronomical potential
722      !!
723      !! ** Method  :   computed from pulsation and amplitude of all tide components
724      !!
725      !! ** Action  :   pot_astro   actronomical potential
726      !!----------------------------------------------------------------------     
727      REAL, INTENT(in)              ::   pdelta      ! Temporal offset in seconds
728      INTEGER                       ::   jk          ! Dummy loop index
729      REAL(wp)                      ::   zt, zramp   ! Local scalars
730      REAL(wp), DIMENSION(nb_harmo) ::   zwt         ! Temporary array
731      !!----------------------------------------------------------------------     
732      !
733      zwt(:) = tide_harmonics(:)%omega * pdelta
734      !
735      IF( ln_tide_ramp ) THEN         ! linear increase if asked
736         zt = rn_tide_ramp_t + pdelta
737         zramp = MIN(  MAX( zt / (rn_tide_ramp_dt*rday) , 0._wp ) , 1._wp  )
738      ENDIF
739      !
740      pot_astro(:,:) = 0._wp          ! update tidal potential (sum of all harmonics)
741      DO jk = 1, nb_harmo
742         IF ( .NOT. ln_tide_dia ) THEN
743            pot_astro(:,:) = pot_astro(:,:) + amp_pot(:,:,jk) * COS( zwt(jk) + phi_pot(:,:,jk) )
744         ELSE
745            pot_astro_comp(:,:) = amp_pot(:,:,jk) * COS( zwt(jk) + phi_pot(:,:,jk) )
746            pot_astro(:,:) = pot_astro(:,:) + pot_astro_comp(:,:)
747            IF ( iom_use( "tide_pot_" // TRIM( tide_harmonics(jk)%cname_tide ) ) ) THEN   ! Output tidal potential (incl. load potential)
748               IF ( ln_tide_ramp ) pot_astro_comp(:,:) = zramp * pot_astro_comp(:,:)
749               CALL iom_put( "tide_pot_" // TRIM( tide_harmonics(jk)%cname_tide ), pot_astro_comp(:,:) )
750            END IF
751         END IF
752      END DO
753      !
754      IF ( ln_tide_ramp ) pot_astro(:,:) = zramp * pot_astro(:,:)
755      !
756      IF( ln_tide_dia ) THEN          ! Output total tidal potential (incl. load potential)
757         IF ( iom_use( "tide_pot" ) ) CALL iom_put( "tide_pot", pot_astro(:,:) + rn_scal_load * sshn(:,:) )
758      END IF
759      !
760   END SUBROUTINE upd_tide
761
762   !!======================================================================
763END MODULE tide_mod
Note: See TracBrowser for help on using the repository browser.