SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
read_seaicen.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! #########
6  SUBROUTINE read_seaice_n (&
7  sg, s, &
8  hprogram,klu,kluout)
9 ! #########################################
10 !
11 !!**** *READ_SEAICE_n* - read seaice scheme variables
12 !!
13 !!
14 !! PURPOSE : feed seaice scheme state variable and 'domain' structure
15 !! -------
16 !!
17 !!** METHOD :
18 !! -------
19 !! For now, only Gelato model is handled
20 !!
21 !! for state variable : quite standard in Surfex : use READ_SURF with
22 !! relevant field names (same names as in genuine gelato restarts)
23 !! for domain information : copy from MODD_SEAFLUX_GRID
24 !! for bathymetry : copy from MODD_SEAFLUX
25 !!
26 !! EXTERNALS : READ_SURF, GLTOOLS_ALLOC, GET_TYPE_DIM, ABOR1_SFX
27 !! --------
28 !!
29 !! IMPLICIT ARGUMENTS : Gelato state variable, and a few namelist parameters
30 !! ------------------
31 !!
32 !! REFERENCE : routine restartr in original Gelato sources (V6.0.20)
33 !! ---------
34 !!
35 !! AUTHOR : S. Sénési *Meteo France*
36 !! ------
37 !!
38 !! MODIFICATIONS
39 !! -------------
40 !! Original 01/2014
41 !-------------------------------------------------------------------------------
42 !
43 !* 0. DECLARATIONS
44 ! ------------
45 !
46 !
47 !
48 !
49 !
51 USE modd_seaflux_n, ONLY : seaflux_t
52 !
53 USE modd_csts, ONLY : xpi, xttsi, xtt
54 USE modd_surf_par, ONLY : xundef
55 USE modd_sfx_oasis, ONLY : lcpl_seaice
56 USE modd_water_par, ONLY : xalbseaice
57 !
58 USE modd_types_glt, ONLY : t_glt
59 USE modd_glt_param, ONLY : nl, nt, nx, ny, nxglo, nyglo, xdomsrf, &
60  xdomsrf_g, nprinto, cfsidmp, chsidmp, &
61  xfsidmpeft, xhsidmpeft, ntd
62 USE modd_glt_const_thm, ONLY : epsil1
63 USE lib_mpp, ONLY : mpp_sum
64 USE modi_glt_sndatmf
65 USE modi_gltools_alloc
66 USE modi_gltools_readnam
67 !
69 USE modi_interpol_sst_mth
70 !
71 USE modi_get_luout
72 USE modi_abor1_sfx
73 USE modd_surfex_omp, ONLY : nblocktot
74 !
75 USE yomhook ,ONLY : lhook, dr_hook
76 USE parkind1 ,ONLY : jprb
77 !
78 IMPLICIT NONE
79 !
80 !* 0.1 Declarations of arguments
81 ! -------------------------
82 !
83 !
84 !
85 !
86 TYPE(seaflux_grid_t), INTENT(INOUT) :: sg
87 TYPE(seaflux_t), INTENT(INOUT) :: s
88 !
89  CHARACTER(LEN=6), INTENT(IN) :: hprogram ! calling program
90 INTEGER, INTENT(IN) :: klu ! number of sea patch point
91 INTEGER, INTENT(IN) :: kluout
92 !
93 !* 0.2 Declarations of local variables
94 ! -------------------------------
95 !
96 INTEGER :: iresp ! Error code after reading
97 !
98 INTEGER :: jmth, inmth
99  CHARACTER(LEN=2 ) :: ymth
100  CHARACTER(LEN=5) :: ylvl
101 !
102  CHARACTER(LEN=12) :: ycateg ! category to read
103  CHARACTER(LEN=12) :: ylevel ! Level to read
104  CHARACTER(LEN=12) :: yrecfm ! Name of the article to be read
105  CHARACTER(LEN=200) :: ymess ! Error Message
106 !
107 INTEGER :: jx,jk,jl ! loop counter on ice categories and layers and grid points
108 INTEGER :: inl_in_file,int_in_file ! file values for ice catgories and layers numbers
109 REAL :: zfsit
110 !
111 REAL(KIND=JPRB) :: zhook_handle
112 !
113 !-------------------------------------------------------------------------------
114 IF (lhook) CALL dr_hook('READ_SEAICE_n',0,zhook_handle)
115 !
116 IF (.NOT.s%LHANDLE_SIC) THEN
117  ALLOCATE(s%XSIC(0))
118  IF (lhook) CALL dr_hook('READ_SEAICE_n',1,zhook_handle)
119  RETURN
120 ENDIF
121 !
122 nx=klu
123 !
124 ALLOCATE(s%XSIC(klu))
125 s%XSIC(:)=xundef
126 !
127 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
128 !
129 ! Dealing with external sea-ice cover data (either for nudging or forcing)
130 !
131 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
132 !
133 IF(s%LINTERPOL_SIC)THEN
134  !
135  ALLOCATE(s%XFSIC(klu))
136  !
137  !Precedent, Current, Next, and Second-next Monthly SIC
138  inmth=4
139  !
140  ALLOCATE(s%XSIC_MTH(klu,inmth))
141  DO jmth=1,inmth
142  WRITE(ymth,'(I2)') (jmth-1)
143  yrecfm='SIC_MTH'//adjustl(ymth(:len_trim(ymth)))
144  CALL read_surf(&
145  hprogram,yrecfm,s%XSIC_MTH(:,jmth),iresp)
146  CALL check_seaice(yrecfm,s%XSIC_MTH(:,jmth))
147  ENDDO
148  !
149  CALL interpol_sst_mth(s, &
150  s%TTIME%TDATE%YEAR,s%TTIME%TDATE%MONTH,s%TTIME%TDATE%DAY,'C',s%XFSIC)
151  !
152  IF (any(s%XFSIC(:)>1.0).OR.any(s%XFSIC(:)<0.0)) THEN
153  CALL abor1_sfx('READ_SEAICE_n: FSIC should be >=0 and <=1')
154  ENDIF
155  !
156 ELSE
157  !
158  ALLOCATE(s%XFSIC(0))
159  ALLOCATE(s%XSIC_MTH(0,0))
160  !
161 ENDIF
162 !
163 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
164 !
165 ! Worrying about a seaice scheme
166 !
167 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
168 !
169  CALL read_surf(&
170  hprogram,'SEAICE_SCHEM',s%CSEAICE_SCHEME,iresp)
171 !
172 IF (trim(s%CSEAICE_SCHEME) == 'GELATO' .AND. (nblocktot>1)) THEN
173  CALL abor1_sfx("READ_SEAICE_n: GELATO CANNOT YET RUN MULTI-THREAD")
174 ENDIF
175 !
176 IF (trim(s%CSEAICE_SCHEME) == 'NONE' ) THEN
177  IF (s%LINTERPOL_SIC ) THEN
178  s%XTICE=s%XSST
179  s%XSIC=s%XFSIC
180  s%XICE_ALB=xalbseaice
181  IF (lhook) CALL dr_hook('READ_SEAICE_n',1,zhook_handle)
182  RETURN
183  ELSE
184  CALL abor1_sfx("READ_SEAICE_n: MUST HAVE CINTERPOL_SIC /= NONE WITH CSEAICE_SCHEME == NONE ")
185  ENDIF
186 ELSE
187  IF (trim(s%CSEAICE_SCHEME) /= 'GELATO') THEN
188  WRITE(kluout,*)'READ_SEAICE_n:CSEAICE_SCHEME read in PREP, ',s%CSEAICE_SCHEME,', is not yet handled'
189  CALL abor1_sfx("READ_SEAICE_n:CAN ONLY HANDLE GELATO SEAICE MODEL YET (and not the one quoted in PREP)")
190  ENDIF
191 ENDIF
192 !
193 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
194 !
195 ! Start of Gelato specifics
196 !
197 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
198 !
199 IF(lcpl_seaice)THEN
200  CALL abor1_sfx('READ_SEAICEN: CANNOT YET MANAGE BOTH TRUE LCPL_SEAICE AND CSEAICE_SCHEME = GELATO')
201 ENDIF
202 nxglo=nx
203 #if ! defined in_arpege
204  CALL mpp_sum(nxglo) ! Should also sum up over NPROMA blocks, in Arpege; but not that easy....
205 #else
206 IF (nprinto > 0) THEN
207  WRITE(kluout,*)'Gelato cannot yet compute global averages when running in Arpege (because of collective comm vs. NPROMA blocks)'
208 ENDIF
209 nxglo=max(nxglo,1)
210 #endif
211 !
212 ! Use convention XSIC_EFOLDING_TIME=0 for avoiding any relaxation
213 ! toward SIC observation and impose it.
214 !
215 IF(s%LINTERPOL_SIC)THEN
216  IF (s%XSIC_EFOLDING_TIME==0.0) THEN
217  cfsidmp='PRESCRIBE'
218  ELSE
219  cfsidmp='DAMP'
220  xfsidmpeft=s%XSIC_EFOLDING_TIME
221  ENDIF
222 ENDIF
223 !
224 IF(s%LINTERPOL_SIT)THEN
225  IF (s%XSIT_EFOLDING_TIME==0.0) THEN
226  chsidmp='PRESCRIBE'
227  ELSE
228  chsidmp='DAMP_FAC'
229  xhsidmpeft= s%XSIT_EFOLDING_TIME
230  ENDIF
231 ENDIF
232 !
233 !* Physical dimensions are set for Gelato , as a 1D field (second dimension is degenerated)
234 !
235 ! Supersedes Gelato hard defaults with a Gelato genuine namelist
236 ! if available (for Gelato wizzards !)
237  CALL gltools_readnam(.false.,kluout)
238 !
239 ny=1
240 nyglo=1
241  CALL gltools_alloc(s%TGLT)
242 !
243 !* 0. Check dimensions : number of layers and ice categories
244 !
245  CALL read_surf(&
246  hprogram,'ICENL',inl_in_file,iresp)
247 IF (inl_in_file /= nl) THEN
248  WRITE(ymess,'("Mismatch in # of seaice layers : prep=",I2," nml=",I2)') inl_in_file, nl
249  CALL abor1_sfx(ymess)
250 END IF
251  CALL read_surf(&
252  hprogram,'ICENT',int_in_file,iresp)
253 IF (int_in_file /= nt) THEN
254  WRITE(ymess,'("Mismatch in # of seaice categories : prep=",I2," nml=",I2)') int_in_file, nt
255  CALL abor1_sfx(ymess)
256 END IF
257 !
258 !* 1. (Semi-)prognostic fields with only space dimension(s) :
259 !
260  CALL read_surf(&
261  hprogram,'ICEUSTAR',s%TGLT%ust(:,1),iresp)
262 !
263 !* 2. Prognostic fields with space and ice-category dimension(s) :
264 !
265 DO jk=1,nt
266  WRITE(ylvl,'(I2)') jk
267  ycateg='_'//adjustl(ylvl)
268  ! .. Read sea ice age for type JK
269  CALL read_surf(&
270  hprogram,'ICEAGE'//ycateg,s%TGLT%sit(jk,:,1)%age,iresp)
271  ! .. Read melt pond volume for type JK
272  CALL read_surf(&
273  hprogram,'ICEVMP'//ycateg,s%TGLT%sit(jk,:,1)%vmp,iresp)
274  ! .. Read sea ice surface albedo for type JK
275  CALL read_surf(&
276  hprogram,'ICEASN'//ycateg,s%TGLT%sit(jk,:,1)%asn,iresp)
277  ! .. Read sea ice fraction for type JK
278  CALL read_surf(&
279  hprogram,'ICEFSI'//ycateg, s%TGLT%sit(jk,:,1)%fsi,iresp)
280  ! .. Read sea ice thickness for type JK
281  CALL read_surf(&
282  hprogram,'ICEHSI'//ycateg, s%TGLT%sit(jk,:,1)%hsi,iresp)
283  ! .. Read sea ice salinity for type JK
284  CALL read_surf(&
285  hprogram,'ICESSI'//ycateg, s%TGLT%sit(jk,:,1)%ssi,iresp)
286  ! .. Read sea ice surface temperature for type JK
287  CALL read_surf(&
288  hprogram,'ICETSF'//ycateg, s%TGLT%sit(jk,:,1)%tsf,iresp)
289  ! .. Read snow thickness for type JK
290  CALL read_surf(&
291  hprogram,'ICEHSN'//ycateg, s%TGLT%sit(jk,:,1)%hsn,iresp)
292  ! .. Read snow density for type JK
293  CALL read_surf(&
294  hprogram,'ICERSN'//ycateg, s%TGLT%sit(jk,:,1)%rsn,iresp)
295  !
296  !* 3. Prognostic fields with space, ice-category and layer dimensions :
297  !
298  DO jl=1,nl
299  WRITE(ylvl,'(I2)') jl
300  ylevel=ycateg(1:len_trim(ycateg))//'_'//adjustl(ylvl)
301  ! .. Read sea ice vertical gltools_enthalpy profile for type JK and level JL
302  CALL read_surf(&
303  hprogram,'ICEH'//ylevel, s%TGLT%sil(jl,jk,:,1)%ent,iresp)
304  END DO
305 END DO
306 !
307 ! 4. Compute ice class existence boolean from ice fractions:
308 !
309 WHERE ( s%TGLT%sit(:,:,1)%fsi<epsil1 )
310  s%TGLT%sit(:,:,1)%esi = .false.
311 ELSEWHERE
312  s%TGLT%sit(:,:,1)%esi = .true.
313 ENDWHERE
314 !
315 ! 4.1 Run original Gelato checks on values read in restart
316 !
317 ! .. Detect negative ice concentrations
318 !
319 DO jx=1,nx
320  DO jl=1,nt
321  IF ( s%TGLT%sit(jl,jx,1)%fsi<0. ) THEN
322  WRITE(kluout,*) &
323  '**** WARNING **** Correcting problem in ice conc. < 0 at i=', &
324  1,' j=',jx,' k=',jl
325  s%TGLT%sit(jl,jx,1)%fsi = 0.
326  ENDIF
327  END DO
328  !
329  zfsit = sum( s%TGLT%sit(:,jx,1)%fsi )
330  !
331  ! .. Detect total concentrations that exceed unity
332  !
333  IF ( zfsit>1. ) THEN
334  WRITE(kluout,*) &
335  '**** WARNING **** Correcting problem in total ice conc. >1 at i=', &
336  1,' j=',jx,' fsi=',zfsit
337  s%TGLT%sit(:,jx,1)%fsi = s%TGLT%sit(:,jx,1)%fsi / zfsit
338  ENDIF
339  !
340  ! .. Detect non zero concentrations but zero thickness (no consequence)
341  !
342  WHERE( s%TGLT%sit(:,jx,1)%fsi>epsil1 .AND. s%TGLT%sit(:,jx,1)%hsi<epsil1)
343  s%TGLT%sit(:,jx,1)%fsi=0.
344  s%TGLT%sit(:,jx,1)%hsi=0.
345  s%TGLT%sit(:,jx,1)%hsn=0.
346  ENDWHERE
347  !
348 END DO
349 
350 ! 5. Initalize Gelato domain parameters
351 !
352 ! All points of Surfex 1D grid in seaflux are sea points
353 !
354 s%TGLT%dom(:,1)%tmk=1
355 s%TGLT%dom(:,1)%imk=1
356 !
357 ! Masks for U- and V- grid point are not used
358 !
359 s%TGLT%dom(:,1)%umk=1
360 s%TGLT%dom(:,1)%vmk=1
361 !
362 ! lat,lon,srf are inherited from seaflux grid
363 !
364 s%TGLT%dom(:,1)%lon=sg%XLON(:)*xpi/180.
365 s%TGLT%dom(:,1)%lat=sg%XLAT(:)*xpi/180.
366 !
367 ! Except in Gelato dynamics, mesh lengths are used only to compute mesh area
368 ! Hence, a simple setting can be used
369 !
370 s%TGLT%dom(:,1)%dxc=sg%XMESH_SIZE(:)**0.5
371 s%TGLT%dom(:,1)%dyc=s%TGLT%dom(:,1)%dxc
372 s%TGLT%dom(:,1)%srf=sg%XMESH_SIZE(:)
373 !
374 ! Surface of local and global ocean domain (ghost points are masked out)
375 !
376 xdomsrf = sum( s%TGLT%dom(:,1)%srf, mask=(s%TGLT%dom(:,1)%tmk==1) )
377 xdomsrf_g = xdomsrf
378 #if ! defined in_arpege
379  CALL mpp_sum(xdomsrf_g)
380 #else
381 ! Avoid zero divide in Gelato computation of global area averages
382 xdomsrf_g = max(xdomsrf_g, 1.e-9)
383 #endif
384 !
385 ! 7. Initalize Gelato time parameters
386 !
387 s%TGLT%ind%beg=1
388 !
389 ! Dummy high value for end time. Implies only that Gelato won't output
390 ! its own format of run-long averaged diagnostics (which are useless
391 ! in Surfex diags logic)
392 !
393 s%TGLT%ind%end=50000000
394 !
395 ! 8. Initalize Gelato bathymetry - change sign w.r.t Surfex
396 !
397 s%TGLT%bat(:,1)=-s%XSEABATHY
398 !
399 !
400 !* Sea ice thickness nudging data
401 !
402 IF(s%LINTERPOL_SIT)THEN
403  !
404  ALLOCATE(s%XFSIT(klu))
405  !
406  !Precedent, Current, Next, and Second-next Monthly SIT
407  inmth=4
408  !
409  ALLOCATE(s%XSIT_MTH(klu,inmth))
410  DO jmth=1,inmth
411  WRITE(ymth,'(I2)') (jmth-1)
412  yrecfm='SIT_MTH'//adjustl(ymth(:len_trim(ymth)))
413  CALL read_surf(&
414  hprogram,yrecfm,s%XSIT_MTH(:,jmth),iresp)
415  CALL check_seaice(yrecfm,s%XSIT_MTH(:,jmth))
416  ENDDO
417  !
418  CALL interpol_sst_mth(s, &
419  s%TTIME%TDATE%YEAR,s%TTIME%TDATE%MONTH,s%TTIME%TDATE%DAY,'H',s%XFSIT)
420  !
421 ELSE
422  !
423  ALLOCATE(s%XFSIT(0))
424  ALLOCATE(s%XSIT_MTH(0,0))
425  !
426 ENDIF
427 !
428 !! Initialize the coupling variables with 'snapshot' prognostic variables
429 ! (for now, averaged over ice categories)
430 !
431  CALL glt_sndatmf( s%TGLT, xttsi - xtt )
432 s%XSIC(:) = s%TGLT%ice_atm(1,:,1)%fsi
433 s%XTICE(:) = s%TGLT%ice_atm(1,:,1)%tsf
434 s%XICE_ALB(:) = s%TGLT%ice_atm(1,:,1)%alb
435 !
436 ! Must init ocean mixed layer temp with sensible value for getting correct diag for time step=0
437 s%TGLT%oce_all(:,1)%tml=s%XSST(:)
438 !
439 IF (lhook) CALL dr_hook('READ_SEAICE_n',1,zhook_handle)
440 !
441 !-------------------------------------------------------------------------------
442  CONTAINS
443 !-------------------------------------------------------------------------------
444 !
445 SUBROUTINE check_seaice(HFIELD,PFIELD)
446 !
447 !
448 IMPLICIT NONE
449 !
450  CHARACTER(LEN=12), INTENT(IN) :: hfield
451 REAL, DIMENSION(:), INTENT(IN) :: pfield
452 !
453 REAL :: zmax,zmin
454 INTEGER :: ji, ierrc
455 !
456 REAL(KIND=JPRB) :: zhook_handle
457 !
458 IF (lhook) CALL dr_hook('READ_SEAICE_n:CHECK_SEAICE',0,zhook_handle)
459 !
460 zmin=-1.0e10
461 zmax=1.0e10
462 !
463 ierrc=0
464 !
465 DO ji=1,klu
466  IF(pfield(ji)>zmax.OR.pfield(ji)<zmin)THEN
467  ierrc=ierrc+1
468  WRITE(kluout,*)'PROBLEM FIELD '//trim(hfield)//' =',pfield(ji),&
469  'NOT REALISTIC AT LOCATION (LAT/LON)',sg%XLAT(ji),sg%XLON(ji)
470  ENDIF
471 ENDDO
472 !
473 IF(ierrc>0) CALL abor1_sfx('READ_SEAICE_n: FIELD '//trim(hfield)//' NOT REALISTIC')
474 !
475 IF (lhook) CALL dr_hook('READ_SEAICE_n:CHECK_SEAICE',1,zhook_handle)
476 
477 END SUBROUTINE check_seaice
478 !
479 !------------------------------------------------------------------------------
480 !
481 END SUBROUTINE read_seaice_n
subroutine gltools_readnam(hmandatory, kluout)
subroutine read_seaice_n(SG, S, HPROGRAM, KLU, KLUOUT)
Definition: read_seaicen.F90:6
subroutine check_seaice(HFIELD, PFIELD)
subroutine abor1_sfx(YTEXT)
Definition: abor1_sfx.F90:6
subroutine interpol_sst_mth(S, KYEAR, KMONTH, KDAY, HFLAG, POUT)
subroutine gltools_alloc(tpglt)
subroutine glt_sndatmf(tpglt, xtmlf)