Changeset 4709
 Timestamp:
 20140711T15:29:31+02:00 (6 years ago)
 Location:
 branches/2014/dev_r4650_UKMO12_CFL_diagnostic/NEMOGCM
 Files:

 5 edited
Legend:
 Unmodified
 Added
 Removed

branches/2014/dev_r4650_UKMO12_CFL_diagnostic/NEMOGCM/CONFIG/SHARED/namelist_ref
r4699 r4709 982 982 ! (no physical validity of the results) 983 983 nn_timing = 0 ! timing by routine activated (=1) creates timing.output file, or not (=0) 984 nn_diacfl = 0 ! Write out cfl diagnostics (=1) in cfl_diagnostics.ascii, or not (=0) 984 985 / 985 986 ! 
branches/2014/dev_r4650_UKMO12_CFL_diagnostic/NEMOGCM/NEMO/OPA_SRC/DIA/diacfl.F90
r4706 r4709 5 5 !!============================================================================== 6 6 !! History : 1.0 ! 201003 (E. Blockley) Original code 7 !! ! 201406 (T Graham) Removed CPP key & Updated to vn3.6 7 8 !! 8 !!9 #if defined key_diacfl10 9 !! 11 10 !! dia_cfl : Compute and output Courant numbers at each timestep … … 16 15 USE lbclnk ! ocean lateral boundary condition (or mpp link) 17 16 USE in_out_manager ! I/O manager 18 USE domvvl 17 USE domvvl 18 USE timing ! Performance output 19 19 20 20 IMPLICIT NONE 21 21 PRIVATE 22 22 23 LOGICAL, PUBLIC, PARAMETER :: lk_diacfl = .TRUE. ! CFL diag flag 24 REAL(wp) :: cu_max, cv_max, cw_max ! daily max U Courant number 25 INTEGER, DIMENSION(3) :: cu_loc, cv_loc, cw_loc ! daily max locations 23 REAL(wp) :: cu_max, cv_max, cw_max ! Run max U Courant number 24 INTEGER, DIMENSION(3) :: cu_loc, cv_loc, cw_loc ! Run max locations 25 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: zcu_cfl ! Courant number arrays 26 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: zcv_cfl ! Courant number arrays 27 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: zcw_cfl ! Courant number arrays 26 28 27 29 INTEGER :: numcfl ! outfile unit … … 29 31 30 32 PUBLIC dia_cfl ! routine called by step.F90 33 PUBLIC dia_cfl_init ! routine called by nemogcm 31 34 32 35 !! * Substitutions … … 53 56 INTEGER, INTENT(in) :: kt ! ocean timestep index 54 57 55 REAL(wp), DIMENSION(jpi,jpj,jpk) :: zcu_cfl ! Courant number arrays56 REAL(wp), DIMENSION(jpi,jpj,jpk) :: zcv_cfl ! " " "57 REAL(wp), DIMENSION(jpi,jpj,jpk) :: zcw_cfl ! " " "58 58 REAL(wp) :: zcu_max, zcv_max, zcw_max ! max Courant numbers per timestep 59 59 INTEGER, DIMENSION(3) :: zcu_loc, zcv_loc, zcw_loc ! max Courant number locations … … 63 63 INTEGER :: ji, jj, jk ! dummy loop indices 64 64 65 66 IF( kt == nit000 ) THEN 65 66 IF( nn_diacfl == 1) THEN 67 IF( nn_timing == 1 ) CALL timing_start('dia_cfl') 68 ! setup timestep multiplier to account for initial Eulerian timestep 69 IF( neuler == 0 .AND. kt == nit000 ) THEN ; dt = rdt 70 ELSE ; dt = rdt * 2.0 71 ENDIF 72 73 ! calculate Courant numbers 74 DO jk = 1, jpk 75 DO jj = 1, jpj 76 DO ji = 1, fs_jpim1 ! vector opt. 77 78 ! Courant number for xdirection (zonal current) 79 zcu_cfl(ji,jj,jk) = ABS(un(ji,jj,jk))*dt/e1u(ji,jj) 80 81 ! Courant number for ydirection (meridional current) 82 zcv_cfl(ji,jj,jk) = ABS(vn(ji,jj,jk))*dt/e2v(ji,jj) 83 84 ! Courant number for zdirection (vertical current) 85 zcw_cfl(ji,jj,jk) = ABS(wn(ji,jj,jk))*dt/fse3w_n(ji,jj,jk) 86 END DO 87 END DO 88 END DO 89 CALL lbc_lnk( zcu_cfl(:,:,:), 'U', 1. ) 90 CALL lbc_lnk( zcv_cfl(:,:,:), 'V', 1. ) 91 CALL lbc_lnk( zcw_cfl(:,:,:), 'W', 1. ) 92 93 ! calculate maximum values and locations 94 IF( lk_mpp ) THEN 95 CALL mpp_maxloc(zcu_cfl,umask,zcu_max, zcu_loc(1), zcu_loc(2), zcu_loc(3)) 96 CALL mpp_maxloc(zcv_cfl,vmask,zcv_max, zcv_loc(1), zcv_loc(2), zcv_loc(3)) 97 CALL mpp_maxloc(zcw_cfl,tmask,zcw_max, zcw_loc(1), zcw_loc(2), zcw_loc(3)) 98 ELSE 99 zlocu = MAXLOC( ABS( zcu_cfl(:,:,:) ) ) 100 zcu_loc(1) = zlocu(1) + nimpp  1 101 zcu_loc(2) = zlocu(2) + njmpp  1 102 zcu_loc(3) = zlocu(3) 103 zcu_max = zcu_cfl(zcu_loc(1),zcu_loc(2),zcu_loc(3)) 104 105 zlocv = MAXLOC( ABS( zcv_cfl(:,:,:) ) ) 106 zcv_loc(1) = zlocv(1) + nimpp  1 107 zcv_loc(2) = zlocv(2) + njmpp  1 108 zcv_loc(3) = zlocv(3) 109 zcv_max = zcv_cfl(zcv_loc(1),zcv_loc(2),zcv_loc(3)) 110 111 zlocw = MAXLOC( ABS( zcw_cfl(:,:,:) ) ) 112 zcw_loc(1) = zlocw(1) + nimpp  1 113 zcw_loc(2) = zlocw(2) + njmpp  1 114 zcw_loc(3) = zlocw(3) 115 zcw_max = zcw_cfl(zcw_loc(1),zcw_loc(2),zcw_loc(3)) 116 ENDIF 117 118 ! write out to file 119 IF( lwp ) THEN 120 WRITE(numcfl,FMT='(2x,i4,5x,a6,5x,f6.4,1x,i4,1x,i4,1x,i4)') kt, 'Max Cu', zcu_max, zcu_loc(1), zcu_loc(2), zcu_loc(3) 121 WRITE(numcfl,FMT='(11x,a6,5x,f6.4,1x,i4,1x,i4,1x,i4)') 'Max Cv', zcv_max, zcv_loc(1), zcv_loc(2), zcv_loc(3) 122 WRITE(numcfl,FMT='(11x,a6,5x,f6.4,1x,i4,1x,i4,1x,i4)') 'Max Cw', zcw_max, zcw_loc(1), zcw_loc(2), zcw_loc(3) 123 ENDIF 124 125 ! update maximum Courant numbers from whole run if applicable 126 IF( zcu_max > cu_max ) THEN 127 cu_max = zcu_max 128 cu_loc = zcu_loc 129 ENDIF 130 IF( zcv_max > cv_max ) THEN 131 cv_max = zcv_max 132 cv_loc = zcv_loc 133 ENDIF 134 IF( zcw_max > cw_max ) THEN 135 cw_max = zcw_max 136 cw_loc = zcw_loc 137 ENDIF 138 139 ! at end of run output max Cu and Cv and close ascii file 140 IF( kt == nitend .AND. lwp ) THEN 141 ! to ascii file 142 WRITE(numcfl,*) '******************************************' 143 WRITE(numcfl,FMT='(3x,a12,7x,f6.4,1x,i4,1x,i4,1x,i4)') 'Run Max Cu', cu_max, cu_loc(1), cu_loc(2), cu_loc(3) 144 WRITE(numcfl,FMT='(3x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cu_max) 145 WRITE(numcfl,*) '******************************************' 146 WRITE(numcfl,FMT='(3x,a12,7x,f6.4,1x,i4,1x,i4,1x,i4)') 'Run Max Cv', cv_max, cv_loc(1), cv_loc(2), cv_loc(3) 147 WRITE(numcfl,FMT='(3x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cv_max) 148 WRITE(numcfl,*) '******************************************' 149 WRITE(numcfl,FMT='(3x,a12,7x,f6.4,1x,i4,1x,i4,1x,i4)') 'Run Max Cw', cw_max, cw_loc(1), cw_loc(2), cw_loc(3) 150 WRITE(numcfl,FMT='(3x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cw_max) 151 CLOSE( numcfl ) 152 153 ! to ocean output 154 WRITE(numout,*) 155 WRITE(numout,*) 'dia_cfl : Maximum Courant number information for the run:' 156 WRITE(numout,*) '~~~~~~~~~~~~' 157 WRITE(numout,FMT='(12x,a12,7x,f6.4,5x,a16,i4,1x,i4,1x,i4,a1)') 'Run Max Cu', cu_max, 'at (i, j, k) = (', cu_loc(1), cu_loc(2), cu_loc(3), ')' 158 WRITE(numout,FMT='(12x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cu_max) 159 WRITE(numout,FMT='(12x,a12,7x,f6.4,5x,a16,i4,1x,i4,1x,i4,a1)') 'Run Max Cv', cv_max, 'at (i, j, k) = (', cv_loc(1), cv_loc(2), cv_loc(3), ')' 160 WRITE(numout,FMT='(12x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cv_max) 161 WRITE(numout,FMT='(12x,a12,7x,f6.4,5x,a16,i4,1x,i4,1x,i4,a1)') 'Run Max Cw', cw_max, 'at (i, j, k) = (', cw_loc(1), cw_loc(2), cw_loc(3), ')' 162 WRITE(numout,FMT='(12x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cw_max) 163 164 ENDIF 165 166 IF( nn_timing == 1 ) CALL timing_stop('dia_cfl') 167 ENDIF 168 169 END SUBROUTINE dia_cfl 170 171 SUBROUTINE dia_cfl_init 172 !! 173 !! *** ROUTINE dia_cfl_init *** 174 !! 175 !! ** Purpose : create output file, initialise arrays 176 !! 177 178 179 IF( nn_diacfl == 1 ) THEN 180 IF( nn_timing == 1 ) CALL timing_start('dia_cfl_init') 181 67 182 cu_max=0.0 68 183 cv_max=0.0 69 184 cw_max=0.0 185 186 ALLOCATE( zcu_cfl(jpi, jpj, jpk), zcv_cfl(jpi, jpj, jpk), zcw_cfl(jpi, jpj, jpk) ) 187 70 188 zcu_cfl(:,:,:)=0.0 71 189 zcv_cfl(:,:,:)=0.0 … … 83 201 WRITE(numcfl,*) '******************************************' 84 202 ENDIF 203 204 IF( nn_timing == 1 ) CALL timing_stop('dia_cfl_init') 205 85 206 ENDIF 86 207 87 ! setup timestep multiplier to account for initial Eulerian timestep 88 IF( neuler == 0 .AND. kt == nit000 ) THEN ; dt = rdt 89 ELSE ; dt = rdt * 2.0 90 ENDIF 91 92 ! calculate Courant numbers 93 DO jk = 1, jpk 94 DO jj = 1, jpj 95 DO ji = 1, fs_jpim1 ! vector opt. 96 97 ! Courant number for xdirection (zonal current) 98 zcu_cfl(ji,jj,jk) = ABS(un(ji,jj,jk))*dt/e1u(ji,jj) 99 100 ! Courant number for ydirection (meridional current) 101 zcv_cfl(ji,jj,jk) = ABS(vn(ji,jj,jk))*dt/e2v(ji,jj) 102 103 ! Courant number for zdirection (vertical current) 104 zcw_cfl(ji,jj,jk) = ABS(wn(ji,jj,jk))*dt/fse3w_n(ji,jj,jk) 105 END DO 106 END DO 107 END DO 108 CALL lbc_lnk( zcu_cfl(:,:,:), 'U', 1. ) 109 CALL lbc_lnk( zcv_cfl(:,:,:), 'V', 1. ) 110 CALL lbc_lnk( zcw_cfl(:,:,:), 'W', 1. ) 111 112 ! calculate maximum values and locations 113 IF( lk_mpp ) THEN 114 CALL mpp_maxloc(zcu_cfl,umask,zcu_max, zcu_loc(1), zcu_loc(2), zcu_loc(3)) 115 CALL mpp_maxloc(zcv_cfl,vmask,zcv_max, zcv_loc(1), zcv_loc(2), zcv_loc(3)) 116 CALL mpp_maxloc(zcw_cfl,tmask,zcw_max, zcw_loc(1), zcw_loc(2), zcw_loc(3)) 117 ELSE 118 zlocu = MAXLOC( ABS( zcu_cfl(:,:,:) ) ) 119 zcu_loc(1) = zlocu(1) + nimpp  1 120 zcu_loc(2) = zlocu(2) + njmpp  1 121 zcu_loc(3) = zlocu(3) 122 zcu_max = zcu_cfl(zcu_loc(1),zcu_loc(2),zcu_loc(3)) 123 124 zlocv = MAXLOC( ABS( zcv_cfl(:,:,:) ) ) 125 zcv_loc(1) = zlocv(1) + nimpp  1 126 zcv_loc(2) = zlocv(2) + njmpp  1 127 zcv_loc(3) = zlocv(3) 128 zcv_max = zcv_cfl(zcv_loc(1),zcv_loc(2),zcv_loc(3)) 129 130 zlocw = MAXLOC( ABS( zcw_cfl(:,:,:) ) ) 131 zcw_loc(1) = zlocw(1) + nimpp  1 132 zcw_loc(2) = zlocw(2) + njmpp  1 133 zcw_loc(3) = zlocw(3) 134 zcw_max = zcw_cfl(zcw_loc(1),zcw_loc(2),zcw_loc(3)) 135 ENDIF 136 137 ! write out to file 138 IF( lwp ) THEN 139 WRITE(numcfl,FMT='(2x,i4,5x,a6,5x,f6.4,1x,i4,1x,i4,1x,i4)') kt, 'Max Cu', zcu_max, zcu_loc(1), zcu_loc(2), zcu_loc(3) 140 WRITE(numcfl,FMT='(11x,a6,5x,f6.4,1x,i4,1x,i4,1x,i4)') 'Max Cv', zcv_max, zcv_loc(1), zcv_loc(2), zcv_loc(3) 141 WRITE(numcfl,FMT='(11x,a6,5x,f6.4,1x,i4,1x,i4,1x,i4)') 'Max Cw', zcw_max, zcw_loc(1), zcw_loc(2), zcw_loc(3) 142 ENDIF 143 144 ! update maximum daily Courant numbers if applicable 145 IF( zcu_max > cu_max ) THEN 146 cu_max = zcu_max 147 cu_loc = zcu_loc 148 ENDIF 149 IF( zcv_max > cv_max ) THEN 150 cv_max = zcv_max 151 cv_loc = zcv_loc 152 ENDIF 153 IF( zcw_max > cw_max ) THEN 154 cw_max = zcw_max 155 cw_loc = zcw_loc 156 ENDIF 157 158 ! at end of run output max Cu and Cv and close ascii file 159 IF( kt == nitend .AND. lwp ) THEN 160 ! to ascii file 161 WRITE(numcfl,*) '******************************************' 162 WRITE(numcfl,FMT='(3x,a12,7x,f6.4,1x,i4,1x,i4,1x,i4)') 'Run Max Cu', cu_max, cu_loc(1), cu_loc(2), cu_loc(3) 163 WRITE(numcfl,FMT='(3x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cu_max) 164 WRITE(numcfl,*) '******************************************' 165 WRITE(numcfl,FMT='(3x,a12,7x,f6.4,1x,i4,1x,i4,1x,i4)') 'Run Max Cv', cv_max, cv_loc(1), cv_loc(2), cv_loc(3) 166 WRITE(numcfl,FMT='(3x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cv_max) 167 WRITE(numcfl,*) '******************************************' 168 WRITE(numcfl,FMT='(3x,a12,7x,f6.4,1x,i4,1x,i4,1x,i4)') 'Run Max Cw', cw_max, cw_loc(1), cw_loc(2), cw_loc(3) 169 WRITE(numcfl,FMT='(3x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cw_max) 170 CLOSE( numcfl ) 171 172 ! to ocean output 173 WRITE(numout,*) 174 WRITE(numout,*) 'dia_cfl : Maximum Courant number information for the run:' 175 WRITE(numout,*) '~~~~~~~~~~~~' 176 WRITE(numout,FMT='(12x,a12,7x,f6.4,5x,a16,i4,1x,i4,1x,i4,a1)') 'Run Max Cu', cu_max, 'at (i, j, k) = (', cu_loc(1), cu_loc(2), cu_loc(3), ')' 177 WRITE(numout,FMT='(12x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cu_max) 178 WRITE(numout,FMT='(12x,a12,7x,f6.4,5x,a16,i4,1x,i4,1x,i4,a1)') 'Run Max Cv', cv_max, 'at (i, j, k) = (', cv_loc(1), cv_loc(2), cv_loc(3), ')' 179 WRITE(numout,FMT='(12x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cv_max) 180 WRITE(numout,FMT='(12x,a12,7x,f6.4,5x,a16,i4,1x,i4,1x,i4,a1)') 'Run Max Cw', cw_max, 'at (i, j, k) = (', cw_loc(1), cw_loc(2), cw_loc(3), ')' 181 WRITE(numout,FMT='(12x,a8,11x,f7.1)') ' => dt/C', dt*(1.0/cw_max) 182 183 ENDIF 184 185 END SUBROUTINE dia_cfl 186 187 #else 188 !! 189 !! Default option : Dummy Module 190 !! 191 LOGICAL, PUBLIC, PARAMETER :: lk_diacfl = .FALSE. ! CFL diag flag 192 CONTAINS 193 SUBROUTINE dia_cfl( kt ) ! Empty routine 194 WRITE(*,*) 'dia_cfl: : You should not have seen this print! error?', kt 195 END SUBROUTINE dia_cfl 196 #endif 197 198 !!====================================================================== 208 END SUBROUTINE dia_cfl_init 209 199 210 END MODULE diacfl 
branches/2014/dev_r4650_UKMO12_CFL_diagnostic/NEMOGCM/NEMO/OPA_SRC/IOM/in_out_manager.F90
r4624 r4709 91 91 LOGICAL :: ln_ctl !: run control for debugging 92 92 INTEGER :: nn_timing !: run control for timing 93 INTEGER :: nn_diacfl !: flag whether to create CFL diagnostics 93 94 INTEGER :: nn_print !: level of print (0 no print) 94 95 INTEGER :: nn_ictls !: Start i indice for the SUM control 
branches/2014/dev_r4650_UKMO12_CFL_diagnostic/NEMOGCM/NEMO/OPA_SRC/nemogcm.F90
r4671 r4709 65 65 USE diadct ! sections transports (dia_dct_init routine) 66 66 USE diaobs ! Observation diagnostics (dia_obs_init routine) 67 USE diacfl ! CFL diagnostics (dia_cfl_init routine) 67 68 USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 68 69 USE step ! NEMO timestepping (stp routine) … … 230 231 NAMELIST/namctl/ ln_ctl, nn_print, nn_ictls, nn_ictle, & 231 232 & nn_isplt, nn_jsplt, nn_jctls, nn_jctle, & 232 & nn_bench, nn_timing 233 & nn_bench, nn_timing, nn_diacfl 233 234 NAMELIST/namcfg/ cp_cfg, cp_cfz, jp_cfg, jpidta, jpjdta, jpkdta, jpiglo, jpjglo, & 234 235 & jpizoom, jpjzoom, jperio … … 453 454 ! Diagnostics 454 455 IF( lk_floats ) CALL flo_init ! drifting Floats 456 CALL dia_cfl_init ! Initialise CFL diagnostics 455 457 IF( lk_diaar5 ) CALL dia_ar5_init ! ar5 diag 456 458 CALL dia_ptr_init ! Poleward TRansports initialization 
branches/2014/dev_r4650_UKMO12_CFL_diagnostic/NEMOGCM/NEMO/OPA_SRC/step.F90
r4706 r4709 202 202 !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 203 203 IF( lk_floats ) CALL flo_stp( kstp ) ! drifting Floats 204 IF( lk_diacfl) CALL dia_cfl( kstp ) ! Courant number diagnostics204 IF( nn_diacfl == 1 ) CALL dia_cfl( kstp ) ! Courant number diagnostics 205 205 IF( lk_diahth ) CALL dia_hth( kstp ) ! Thermocline depth (20 degres isotherm depth) 206 206 IF( lk_diafwb ) CALL dia_fwb( kstp ) ! Fresh water budget diagnostics
Note: See TracChangeset
for help on using the changeset viewer.