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 @ 11864

Last change on this file since 11864 was 11864, checked in by smueller, 5 years ago

Inclusion of string normalisation in subroutine tide_init_components of module tide_mod to permit the selection of tidal constituents irrespective of the capitalisation of their identifiers specified in the namelist (ticket #2194)

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