source: LMDZ6/branches/ICOLMDZISO/libf/phylmdiso/phyaqua_mod.F90 @ 5591

Last change on this file since 5591 was 5084, checked in by Laurent Fairhead, 16 months ago

Reverting to r4065. Updating fortran standard broke too much stuff. Will do it by smaller chunks
AB, LF

File size: 32.1 KB
Line 
1!
2! $Id: phyaqua_mod.F90 3579 2019-10-09 13:11:07Z fairhead $
3!
4MODULE phyaqua_mod
5  ! Routines complementaires pour la physique planetaire.
6  IMPLICIT NONE
7
8CONTAINS
9
10  SUBROUTINE iniaqua(nlon,year_len,iflag_phys)
11
12    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
13    ! Creation d'un etat initial et de conditions aux limites
14    ! (resp startphy.nc et limit.nc) pour des configurations idealisees
15    ! du modele LMDZ dans sa version terrestre.
16    ! iflag_phys est un parametre qui controle
17    ! iflag_phys = N
18    ! de 100 a 199 : aqua planetes avec SST forcees
19    ! N-100 determine le type de SSTs
20    ! de 200 a 299 : terra planetes avec Ts calcule
21
22    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23
24    USE dimphy, ONLY: klon
25    USE geometry_mod, ONLY : latitude
26    USE surface_data, ONLY: type_ocean, ok_veget
27    USE pbl_surface_mod, ONLY: pbl_surface_init
28    USE fonte_neige_mod, ONLY: fonte_neige_init
29#ifdef ISO
30  USE fonte_neige_mod,  ONLY : fonte_neige_init_iso
31  USE pbl_surface_mod,  ONLY : pbl_surface_init_iso
32#endif
33    USE phys_state_var_mod
34    USE time_phylmdz_mod, ONLY: day_ref, ndays, pdtphys, &
35                                day_ini,day_end
36    USE indice_sol_mod
37    USE nrtype, ONLY: pi
38!    USE ioipsl
39    USE mod_phys_lmdz_para, ONLY: is_master
40    USE mod_phys_lmdz_transfert_para, ONLY: bcast
41    USE mod_grid_phy_lmdz
42    USE ioipsl_getin_p_mod, ONLY : getin_p
43    USE phys_cal_mod , ONLY: calend, year_len_phy => year_len
44#ifdef ISO
45  USE infotrac_phy, ONLY: niso
46#endif
47
48    IMPLICIT NONE
49
50    include "YOMCST.h"
51    include "clesphys.h"
52    include "dimsoil.h"
53
54    INTEGER, INTENT (IN) :: nlon, year_len, iflag_phys
55    ! IM ajout latfi, lonfi
56!    REAL, INTENT (IN) :: lonfi(nlon), latfi(nlon)
57
58    INTEGER type_profil, type_aqua
59
60    ! Ajouts initialisation des surfaces
61    REAL :: run_off_lic_0(nlon)
62    REAL :: qsolsrf(nlon, nbsrf), snsrf(nlon, nbsrf)
63    REAL :: tsoil(nlon, nsoilmx, nbsrf)
64    REAL :: tslab(nlon), seaice(nlon)
65    REAL fder(nlon)
66
67#ifdef ISO
68    REAL :: xtrun_off_lic_0(niso,nlon)
69    REAL :: xtsolsrf(niso,nlon, nbsrf), xtsnsrf(niso,nlon, nbsrf)
70    REAL :: Rland_ice(niso,nlon)
71#endif
72
73
74
75    ! Arguments :
76    ! -----------
77
78    ! integer radpas
79    INTEGER it, unit, i, k, itap
80
81    REAL rugos, albedo
82    REAL tsurf
83    REAL time, timestep, day, day0
84    REAL qsol_f
85    REAL rugsrel(nlon)
86    LOGICAL alb_ocean
87
88    CHARACTER *80 ans, file_forctl, file_fordat, file_start
89    CHARACTER *100 file, var
90    CHARACTER *2 cnbl
91
92    REAL phy_nat(nlon, year_len)
93    REAL phy_alb(nlon, year_len)
94    REAL phy_sst(nlon, year_len)
95    REAL phy_bil(nlon, year_len)
96    REAL phy_rug(nlon, year_len)
97    REAL phy_ice(nlon, year_len)
98    REAL phy_fter(nlon, year_len)
99    REAL phy_foce(nlon, year_len)
100    REAL phy_fsic(nlon, year_len)
101    REAL phy_flic(nlon, year_len)
102
103    INTEGER, SAVE :: read_climoz = 0 ! read ozone climatology
104!$OMP THREADPRIVATE(read_climoz)
105
106    ! -------------------------------------------------------------------------
107    ! declaration pour l'appel a phyredem
108    ! -------------------------------------------------------------------------
109
110    ! real pctsrf(nlon,nbsrf),ftsol(nlon,nbsrf)
111    REAL falbe(nlon, nbsrf), falblw(nlon, nbsrf)
112    ! real pbl_tke(nlon,llm,nbsrf)
113    ! real rain_fall(nlon),snow_fall(nlon)
114    ! real solsw(nlon), sollw(nlon),radsol(nlon)
115    ! real t_ancien(nlon,llm),q_ancien(nlon,llm),rnebcon(nlon,llm)
116    ! real ratqs(nlon,llm)
117    ! real clwcon(nlon,llm)
118
119    INTEGER longcles
120    PARAMETER (longcles=20)
121    REAL clesphy0(longcles)
122
123
124    ! -----------------------------------------------------------------------
125    ! dynamial tendencies :
126    ! ---------------------
127
128    INTEGER l, ierr, aslun
129
130    REAL paire
131
132    ! Local
133    CHARACTER (LEN=20) :: modname='phyaqua'
134    CHARACTER (LEN=80) :: abort_message
135
136
137    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
138    ! INITIALISATIONS
139    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
140
141    ! -----------------------------------------------------------------------
142    ! Initialisations  des constantes
143    ! -------------------------------
144
145    !IF (calend .EQ. "earth_360d") Then
146      year_len_phy = year_len
147    !END IF
148   
149    if (year_len.ne.360) then
150      write (*,*) year_len
151      write (*,*) 'iniaqua: 360 day calendar is required !'
152      stop
153    endif
154
155    type_aqua = iflag_phys/100
156    type_profil = iflag_phys - type_aqua*100
157    PRINT *, 'iniaqua:type_aqua, type_profil', type_aqua, type_profil
158
159    IF (klon/=nlon) THEN
160      WRITE (*, *) 'iniaqua: klon=', klon, ' nlon=', nlon
161      abort_message= 'probleme de dimensions dans iniaqua'
162      CALL abort_physic(modname,abort_message,1)
163    END IF
164    CALL phys_state_var_init(read_climoz)
165
166
167    read_climoz = 0
168    day0 = 217.
169    day = day0
170    it = 0
171    time = 0.
172
173    ! -----------------------------------------------------------------------
174    ! initialisations de la physique
175    ! -----------------------------------------------------------------------
176
177    day_ini = day_ref
178    day_end = day_ini + ndays
179
180    nbapp_rad = 24
181    CALL getin_p('nbapp_rad', nbapp_rad)
182
183    ! ---------------------------------------------------------------------
184    ! Creation des conditions aux limites:
185    ! ------------------------------------
186    ! Initialisations des constantes
187    ! Ajouter les manquants dans planete.def... (albedo etc)
188    co2_ppm = 348.
189    CALL getin_p('co2_ppm', co2_ppm)
190
191    solaire = 1365.
192    CALL getin_p('solaire', solaire)
193 
194    ! CALL getin('albedo',albedo) ! albedo is set below, depending on
195    ! type_aqua
196    alb_ocean = .TRUE.
197    CALL getin_p('alb_ocean', alb_ocean)
198
199    WRITE (*, *) 'iniaqua: co2_ppm=', co2_ppm
200    WRITE (*, *) 'iniaqua: solaire=', solaire
201    WRITE (*, *) 'iniaqua: alb_ocean=', alb_ocean
202
203    radsol = 0.
204    qsol_f = 10.
205
206    ! Conditions aux limites:
207    ! -----------------------
208
209    qsol(:) = qsol_f
210    rugsrel = 0.0 ! (rugsrel = rugoro)
211    rugoro = 0.0
212    u_ancien = 0.0
213    v_ancien = 0.0
214    agesno = 50.0
215    ! Relief plat
216    zmea = 0.
217    zstd = 0.
218    zsig = 0.
219    zgam = 0.
220    zthe = 0.
221    zpic = 0.
222    zval = 0.
223
224    ! Une seule surface
225    pctsrf = 0.
226    IF (type_aqua==1) THEN
227      rugos = 1.E-4
228      albedo = 0.19
229      pctsrf(:, is_oce) = 1.
230    ELSE IF (type_aqua==2) THEN
231      rugos = 0.03
232      albedo = 0.1
233      pctsrf(:, is_ter) = 1.
234    END IF
235
236    CALL getin_p('rugos', rugos)
237
238    WRITE (*, *) 'iniaqua: rugos=', rugos
239    zmasq(:) = pctsrf(:, is_ter)
240
241    ! pctsrf_pot(:,is_oce) = 1. - zmasq(:)
242    ! pctsrf_pot(:,is_sic) = 1. - zmasq(:)
243
244    ! Si alb_ocean on calcule un albedo oceanique moyen
245    ! if (alb_ocean) then
246    ! Voir pourquoi on avait ca.
247    ! CALL ini_alb_oce(phy_alb)
248    ! else
249    phy_alb(:, :) = albedo ! albedo land only (old value condsurf_jyg=0.3)
250    ! endif !alb_ocean
251
252    DO i = 1, year_len
253      ! IM Terraplanete   phy_sst(:,i) = 260.+50.*cos(rlatd(:))**2
254      ! IM ajout calcul profil sst selon le cas considere (cf. FBr)
255
256      phy_nat(:, i) = 1.0 ! 0=ocean libre, 1=land, 2=glacier, 3=banquise
257      phy_bil(:, i) = 1.0 ! ne sert que pour les slab_ocean
258      phy_rug(:, i) = rugos ! longueur rugosite utilisee sur land only
259      phy_ice(:, i) = 0.0 ! fraction de glace (?)
260      phy_fter(:, i) = pctsrf(:, is_ter) ! fraction de glace (?)
261      phy_foce(:, i) = pctsrf(:, is_oce) ! fraction de glace (?)
262      phy_fsic(:, i) = pctsrf(:, is_sic) ! fraction de glace (?)
263      phy_flic(:, i) = pctsrf(:, is_lic) ! fraction de glace (?)
264    END DO
265    ! IM calcul profil sst
266    CALL profil_sst(nlon, latitude, type_profil, phy_sst)
267
268    IF (grid_type==unstructured) THEN
269      CALL writelim_unstruct(klon, phy_nat, phy_alb, phy_sst, phy_bil, phy_rug, phy_ice, &
270                             phy_fter, phy_foce, phy_flic, phy_fsic)
271    ELSE
272     
273       CALL writelim(klon, phy_nat, phy_alb, phy_sst, phy_bil, phy_rug, phy_ice, &
274                     phy_fter, phy_foce, phy_flic, phy_fsic)
275    ENDIF
276
277    ! ---------------------------------------------------------------------
278    ! Ecriture de l'etat initial:
279    ! ---------------------------
280
281
282    ! Ecriture etat initial physique
283
284    timestep = pdtphys
285    radpas = nint(rday/timestep/float(nbapp_rad))
286
287    DO i = 1, longcles
288      clesphy0(i) = 0.
289    END DO
290    clesphy0(1) = float(iflag_con)
291    clesphy0(2) = float(nbapp_rad)
292    ! IF( cycle_diurne  ) clesphy0(3) =  1.
293    clesphy0(3) = 1. ! cycle_diurne
294    clesphy0(4) = 1. ! soil_model
295    clesphy0(5) = 1. ! new_oliq
296    clesphy0(6) = 0. ! ok_orodr
297    clesphy0(7) = 0. ! ok_orolf
298    clesphy0(8) = 0. ! ok_limitvrai
299
300
301    ! =======================================================================
302    ! Profils initiaux
303    ! =======================================================================
304
305    ! On initialise les temperatures de surfaces comme les sst
306    DO i = 1, nlon
307      ftsol(i, :) = phy_sst(i, 1)
308      tsoil(i, :, :) = phy_sst(i, 1)
309      tslab(i) = phy_sst(i, 1)
310    END DO
311
312    falbe(:, :) = albedo
313    falblw(:, :) = albedo
314    rain_fall(:) = 0.
315    snow_fall(:) = 0.
316    solsw(:) = 0.
317    sollw(:) = 0.
318    radsol(:) = 0.
319
320    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
321    ! intialisation bidon mais pas grave
322    t_ancien(:, :) = 0.
323    q_ancien(:, :) = 0.
324    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
325    rnebcon = 0.
326    ratqs = 0.
327    clwcon = 0.
328    pbl_tke = 1.E-8
329
330    ! variables supplementaires pour appel a plb_surface_init
331    fder(:) = 0.
332    seaice(:) = 0.
333    run_off_lic_0 = 0.
334    fevap = 0.
335#ifdef ISO
336    xtrun_off_lic_0 = 0.
337#endif
338
339
340    ! Initialisations necessaires avant phyredem
341    type_ocean = 'force'
342    CALL fonte_neige_init(run_off_lic_0)
343#ifdef ISO
344   CALL fonte_neige_init_iso(xtrun_off_lic_0)
345#endif
346    qsolsrf(:, :) = qsol(1) ! humidite du sol des sous surface
347    snsrf(:, :) = 0. ! couverture de neige des sous surface
348    z0m(:, :) = rugos ! couverture de neige des sous surface
349    z0h=z0m
350
351
352    CALL pbl_surface_init(fder, snsrf, qsolsrf, tsoil)
353#ifdef ISO
354  CALL pbl_surface_init_iso(xtsnsrf,Rland_ice)
355#endif
356
357    PRINT *, 'iniaqua: before phyredem'
358
359    pbl_tke(:,:,:) = 1.e-8
360    falb1 = albedo
361    falb2 = albedo
362    zmax0 = 0.
363    f0 = 0.
364    sig1 = 0.
365    w01 = 0.
366    wake_deltat = 0.
367    wake_deltaq = 0.
368    wake_s = 0.
369    wake_dens = 0.
370    wake_cstar = 0.
371    wake_pe = 0.
372    wake_fip = 0.
373    fm_therm = 0.
374    entr_therm = 0.
375    detr_therm = 0.
376    ale_bl = 0.
377    ale_bl_trig =0.
378    alp_bl =0.
379    treedrg(:,:,:)=0.
380
381    u10m = 0.
382    v10m = 0.
383
384    ql_ancien   = 0.
385    qs_ancien   = 0.
386    u_ancien    = 0.
387    v_ancien    = 0.
388    prw_ancien  = 0.
389    prlw_ancien = 0.
390    prsw_ancien = 0. 
391
392    ale_wake    = 0.
393    ale_bl_stat = 0. 
394
395
396!ym error : the sub surface dimension is the third not second : forgotten for iniaqua
397!    falb_dir(:,is_ter,:)=0.08; falb_dir(:,is_lic,:)=0.6
398!    falb_dir(:,is_oce,:)=0.5;  falb_dir(:,is_sic,:)=0.6
399    falb_dir(:,:,is_ter)=0.08; falb_dir(:,:,is_lic)=0.6
400    falb_dir(:,:,is_oce)=0.5;  falb_dir(:,:,is_sic)=0.6
401
402!ym falb_dif has been forgotten, initialize with defaukt value found in phyetat0 or 0 ?
403!ym probably the uninitialized value was 0 for standard (regular grid) case
404    falb_dif(:,:,:)=0
405
406
407    CALL phyredem('startphy.nc')
408
409    PRINT *, 'iniaqua: after phyredem'
410    CALL phys_state_var_end
411
412    RETURN
413  END SUBROUTINE iniaqua
414
415
416  ! ====================================================================
417  ! ====================================================================
418  SUBROUTINE zenang_an(cycle_diurne, gmtime, rlat, rlon, rmu0, fract)
419    USE dimphy
420    IMPLICIT NONE
421    ! ====================================================================
422    ! =============================================================
423    ! CALL zenang(cycle_diurne,gmtime,rlat,rlon,rmu0,fract)
424    ! Auteur : A. Campoy et F. Hourdin
425    ! Objet  : calculer les valeurs moyennes du cos de l'angle zenithal
426    ! et l'ensoleillement moyen entre gmtime1 et gmtime2
427    ! connaissant la declinaison, la latitude et la longitude.
428
429    ! Dans cette version particuliere, on calcule le rayonnement
430    ! moyen sur l'année à chaque latitude.
431    ! angle zenithal calculé pour obtenir un
432    ! Fit polynomial de  l'ensoleillement moyen au sommet de l'atmosphere
433    ! en moyenne annuelle.
434    ! Spécifique de la terre. Utilisé pour les aqua planetes.
435
436    ! Rque   : Different de la routine angle en ce sens que zenang
437    ! fournit des moyennes de pmu0 et non des valeurs
438    ! instantanees, du coup frac prend toutes les valeurs
439    ! entre 0 et 1.
440    ! Date   : premiere version le 13 decembre 1994
441    ! revu pour  GCM  le 30 septembre 1996
442    ! ===============================================================
443    ! longi----INPUT : la longitude vraie de la terre dans son plan
444    ! solaire a partir de l'equinoxe de printemps (degre)
445    ! gmtime---INPUT : temps universel en fraction de jour
446    ! pdtrad---INPUT : pas de temps du rayonnement (secondes)
447    ! lat------INPUT : latitude en degres
448    ! long-----INPUT : longitude en degres
449    ! pmu0-----OUTPUT: angle zenithal moyen entre gmtime et gmtime+pdtrad
450    ! frac-----OUTPUT: ensoleillement moyen entre gmtime et gmtime+pdtrad
451    ! ================================================================
452    include "YOMCST.h"
453    ! ================================================================
454    LOGICAL cycle_diurne
455    REAL gmtime
456    REAL rlat(klon), rlon(klon), rmu0(klon), fract(klon)
457    ! ================================================================
458    INTEGER i
459    REAL gmtime1, gmtime2
460    REAL pi_local
461
462
463    REAL rmu0m(klon), rmu0a(klon)
464
465
466    pi_local = 4.0*atan(1.0)
467
468    ! ================================================================
469    ! Calcul de l'angle zenithal moyen sur la journee
470    ! ================================================================
471
472    DO i = 1, klon
473      fract(i) = 1.
474      ! Calcule du flux moyen
475      IF (abs(rlat(i))<=28.75) THEN
476        rmu0m(i) = (210.1924+206.6059*cos(0.0174533*rlat(i))**2)/1365.
477      ELSE IF (abs(rlat(i))<=43.75) THEN
478        rmu0m(i) = (187.4562+236.1853*cos(0.0174533*rlat(i))**2)/1365.
479      ELSE IF (abs(rlat(i))<=71.25) THEN
480        rmu0m(i) = (162.4439+284.1192*cos(0.0174533*rlat(i))**2)/1365.
481      ELSE
482        rmu0m(i) = (172.8125+183.7673*cos(0.0174533*rlat(i))**2)/1365.
483      END IF
484    END DO
485
486    ! ================================================================
487    ! Avec ou sans cycle diurne
488    ! ================================================================
489
490    IF (cycle_diurne) THEN
491
492      ! On redecompose flux  au sommet suivant un cycle diurne idealise
493      ! identique a toutes les latitudes.
494
495      DO i = 1, klon
496        rmu0a(i) = 2.*rmu0m(i)*sqrt(2.)*pi_local/(4.-pi_local)
497        rmu0(i) = rmu0a(i)*abs(sin(pi_local*gmtime+pi_local*rlon(i)/360.)) - &
498          rmu0a(i)/sqrt(2.)
499      END DO
500
501      DO i = 1, klon
502        IF (rmu0(i)<=0.) THEN
503          rmu0(i) = 0.
504          fract(i) = 0.
505        ELSE
506          fract(i) = 1.
507        END IF
508      END DO
509
510      ! Affichage de l'angel zenitale
511      ! print*,'************************************'
512      ! print*,'************************************'
513      ! print*,'************************************'
514      ! print*,'latitude=',rlat(i),'longitude=',rlon(i)
515      ! print*,'rmu0m=',rmu0m(i)
516      ! print*,'rmu0a=',rmu0a(i)
517      ! print*,'rmu0=',rmu0(i)
518
519    ELSE
520
521      DO i = 1, klon
522        fract(i) = 0.5
523        rmu0(i) = rmu0m(i)*2.
524      END DO
525
526    END IF
527
528    RETURN
529  END SUBROUTINE zenang_an
530
531  ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
532
533  SUBROUTINE writelim_unstruct(klon, phy_nat, phy_alb, phy_sst, phy_bil, phy_rug, &
534      phy_ice, phy_fter, phy_foce, phy_flic, phy_fsic)
535
536    USE mod_phys_lmdz_para, ONLY: is_omp_master, klon_mpi
537    USE mod_phys_lmdz_transfert_para, ONLY: gather_omp
538    USE lmdz_xios
539    IMPLICIT NONE
540
541    include "netcdf.inc"
542
543    INTEGER, INTENT (IN) :: klon
544    REAL, INTENT (IN) :: phy_nat(klon, 360)
545    REAL, INTENT (IN) :: phy_alb(klon, 360)
546    REAL, INTENT (IN) :: phy_sst(klon, 360)
547    REAL, INTENT (IN) :: phy_bil(klon, 360)
548    REAL, INTENT (IN) :: phy_rug(klon, 360)
549    REAL, INTENT (IN) :: phy_ice(klon, 360)
550    REAL, INTENT (IN) :: phy_fter(klon, 360)
551    REAL, INTENT (IN) :: phy_foce(klon, 360)
552    REAL, INTENT (IN) :: phy_flic(klon, 360)
553    REAL, INTENT (IN) :: phy_fsic(klon, 360)
554
555    REAL :: phy_mpi(klon_mpi, 360) ! temporary variable, to store phy_***(:)
556      ! on the whole physics grid
557 
558    PRINT *, 'writelim: Ecriture du fichier limit'
559
560    CALL gather_omp(phy_foce, phy_mpi)
561    IF (is_omp_master) CALL xios_send_field('foce_limout',phy_mpi)
562
563    CALL gather_omp(phy_fsic, phy_mpi)
564    IF (is_omp_master) CALL xios_send_field('fsic_limout',phy_mpi)
565     
566    CALL gather_omp(phy_fter, phy_mpi)
567    IF (is_omp_master) CALL xios_send_field('fter_limout',phy_mpi)
568     
569    CALL gather_omp(phy_flic, phy_mpi)
570    IF (is_omp_master) CALL xios_send_field('flic_limout',phy_mpi)
571
572    CALL gather_omp(phy_sst, phy_mpi)
573    IF (is_omp_master) CALL xios_send_field('sst_limout',phy_mpi)
574
575    CALL gather_omp(phy_bil, phy_mpi)
576    IF (is_omp_master) CALL xios_send_field('bils_limout',phy_mpi)
577
578    CALL gather_omp(phy_alb, phy_mpi)
579    IF (is_omp_master) CALL xios_send_field('alb_limout',phy_mpi)
580
581    CALL gather_omp(phy_rug, phy_mpi)
582    IF (is_omp_master) CALL xios_send_field('rug_limout',phy_mpi)
583
584  END SUBROUTINE writelim_unstruct
585
586
587
588  SUBROUTINE writelim(klon, phy_nat, phy_alb, phy_sst, phy_bil, phy_rug, &
589      phy_ice, phy_fter, phy_foce, phy_flic, phy_fsic)
590
591    USE mod_phys_lmdz_para, ONLY: is_master
592    USE mod_grid_phy_lmdz, ONLY: klon_glo
593    USE mod_phys_lmdz_transfert_para, ONLY: gather
594    USE phys_cal_mod, ONLY: year_len
595    IMPLICIT NONE
596    include "netcdf.inc"
597
598    INTEGER, INTENT (IN) :: klon
599    REAL, INTENT (IN) :: phy_nat(klon, year_len)
600    REAL, INTENT (IN) :: phy_alb(klon, year_len)
601    REAL, INTENT (IN) :: phy_sst(klon, year_len)
602    REAL, INTENT (IN) :: phy_bil(klon, year_len)
603    REAL, INTENT (IN) :: phy_rug(klon, year_len)
604    REAL, INTENT (IN) :: phy_ice(klon, year_len)
605    REAL, INTENT (IN) :: phy_fter(klon, year_len)
606    REAL, INTENT (IN) :: phy_foce(klon, year_len)
607    REAL, INTENT (IN) :: phy_flic(klon, year_len)
608    REAL, INTENT (IN) :: phy_fsic(klon, year_len)
609
610    REAL :: phy_glo(klon_glo, year_len) ! temporary variable, to store phy_***(:)
611      ! on the whole physics grid
612    INTEGER :: k
613    INTEGER ierr
614    INTEGER dimfirst(3)
615    INTEGER dimlast(3)
616
617    INTEGER nid, ndim, ntim
618    INTEGER dims(2), debut(2), epais(2)
619    INTEGER id_tim
620    INTEGER id_nat, id_sst, id_bils, id_rug, id_alb
621    INTEGER id_fter, id_foce, id_fsic, id_flic
622
623    IF (is_master) THEN
624
625      PRINT *, 'writelim: Ecriture du fichier limit'
626
627      ierr = nf_create('limit.nc', IOR(NF_CLOBBER,NF_64BIT_OFFSET), nid)
628
629      ierr = nf_put_att_text(nid, nf_global, 'title', 30, &
630        'Fichier conditions aux limites')
631      ! !        ierr = NF_DEF_DIM (nid, "points_physiques", klon, ndim)
632      ierr = nf_def_dim(nid, 'points_physiques', klon_glo, ndim)
633      ierr = nf_def_dim(nid, 'time', nf_unlimited, ntim)
634
635      dims(1) = ndim
636      dims(2) = ntim
637
638#ifdef NC_DOUBLE
639      ierr = nf_def_var(nid, 'TEMPS', nf_double, 1, ntim, id_tim)
640#else
641      ierr = nf_def_var(nid, 'TEMPS', nf_float, 1, ntim, id_tim)
642#endif
643      ierr = nf_put_att_text(nid, id_tim, 'title', 17, 'Jour dans l annee')
644
645#ifdef NC_DOUBLE
646      ierr = nf_def_var(nid, 'NAT', nf_double, 2, dims, id_nat)
647#else
648      ierr = nf_def_var(nid, 'NAT', nf_float, 2, dims, id_nat)
649#endif
650      ierr = nf_put_att_text(nid, id_nat, 'title', 23, &
651        'Nature du sol (0,1,2,3)')
652
653#ifdef NC_DOUBLE
654      ierr = nf_def_var(nid, 'SST', nf_double, 2, dims, id_sst)
655#else
656      ierr = nf_def_var(nid, 'SST', nf_float, 2, dims, id_sst)
657#endif
658      ierr = nf_put_att_text(nid, id_sst, 'title', 35, &
659        'Temperature superficielle de la mer')
660
661#ifdef NC_DOUBLE
662      ierr = nf_def_var(nid, 'BILS', nf_double, 2, dims, id_bils)
663#else
664      ierr = nf_def_var(nid, 'BILS', nf_float, 2, dims, id_bils)
665#endif
666      ierr = nf_put_att_text(nid, id_bils, 'title', 32, &
667        'Reference flux de chaleur au sol')
668
669#ifdef NC_DOUBLE
670      ierr = nf_def_var(nid, 'ALB', nf_double, 2, dims, id_alb)
671#else
672      ierr = nf_def_var(nid, 'ALB', nf_float, 2, dims, id_alb)
673#endif
674      ierr = nf_put_att_text(nid, id_alb, 'title', 19, 'Albedo a la surface')
675
676#ifdef NC_DOUBLE
677      ierr = nf_def_var(nid, 'RUG', nf_double, 2, dims, id_rug)
678#else
679      ierr = nf_def_var(nid, 'RUG', nf_float, 2, dims, id_rug)
680#endif
681      ierr = nf_put_att_text(nid, id_rug, 'title', 8, 'Rugosite')
682
683#ifdef NC_DOUBLE
684      ierr = nf_def_var(nid, 'FTER', nf_double, 2, dims, id_fter)
685#else
686      ierr = nf_def_var(nid, 'FTER', nf_float, 2, dims, id_fter)
687#endif
688      ierr = nf_put_att_text(nid, id_fter, 'title',10,'Frac. Land')
689#ifdef NC_DOUBLE
690      ierr = nf_def_var(nid, 'FOCE', nf_double, 2, dims, id_foce)
691#else
692      ierr = nf_def_var(nid, 'FOCE', nf_float, 2, dims, id_foce)
693#endif
694      ierr = nf_put_att_text(nid, id_foce, 'title',11,'Frac. Ocean')
695#ifdef NC_DOUBLE
696      ierr = nf_def_var(nid, 'FSIC', nf_double, 2, dims, id_fsic)
697#else
698      ierr = nf_def_var(nid, 'FSIC', nf_float, 2, dims, id_fsic)
699#endif
700      ierr = nf_put_att_text(nid, id_fsic, 'title',13,'Frac. Sea Ice')
701#ifdef NC_DOUBLE
702      ierr = nf_def_var(nid, 'FLIC', nf_double, 2, dims, id_flic)
703#else
704      ierr = nf_def_var(nid, 'FLIC', nf_float, 2, dims, id_flic)
705#endif
706      ierr = nf_put_att_text(nid, id_flic, 'title',14,'Frac. Land Ice')
707
708      ierr = nf_enddef(nid)
709      IF (ierr/=nf_noerr) THEN
710        WRITE (*, *) 'writelim error: failed to end define mode'
711        WRITE (*, *) nf_strerror(ierr)
712      END IF
713
714
715      ! write the 'times'
716      DO k = 1, year_len
717#ifdef NC_DOUBLE
718        ierr = nf_put_var1_double(nid, id_tim, k, dble(k))
719#else
720        ierr = nf_put_var1_real(nid, id_tim, k, float(k))
721#endif
722        IF (ierr/=nf_noerr) THEN
723          WRITE (*, *) 'writelim error with temps(k),k=', k
724          WRITE (*, *) nf_strerror(ierr)
725        END IF
726      END DO
727
728    END IF ! of if (is_master)
729
730    ! write the fields, after having collected them on master
731
732    CALL gather(phy_nat, phy_glo)
733    IF (is_master) THEN
734#ifdef NC_DOUBLE
735      ierr = nf_put_var_double(nid, id_nat, phy_glo)
736#else
737      ierr = nf_put_var_real(nid, id_nat, phy_glo)
738#endif
739      IF (ierr/=nf_noerr) THEN
740        WRITE (*, *) 'writelim error with phy_nat'
741        WRITE (*, *) nf_strerror(ierr)
742      END IF
743    END IF
744
745    CALL gather(phy_sst, phy_glo)
746    IF (is_master) THEN
747#ifdef NC_DOUBLE
748      ierr = nf_put_var_double(nid, id_sst, phy_glo)
749#else
750      ierr = nf_put_var_real(nid, id_sst, phy_glo)
751#endif
752      IF (ierr/=nf_noerr) THEN
753        WRITE (*, *) 'writelim error with phy_sst'
754        WRITE (*, *) nf_strerror(ierr)
755      END IF
756    END IF
757
758    CALL gather(phy_bil, phy_glo)
759    IF (is_master) THEN
760#ifdef NC_DOUBLE
761      ierr = nf_put_var_double(nid, id_bils, phy_glo)
762#else
763      ierr = nf_put_var_real(nid, id_bils, phy_glo)
764#endif
765      IF (ierr/=nf_noerr) THEN
766        WRITE (*, *) 'writelim error with phy_bil'
767        WRITE (*, *) nf_strerror(ierr)
768      END IF
769    END IF
770
771    CALL gather(phy_alb, phy_glo)
772    IF (is_master) THEN
773#ifdef NC_DOUBLE
774      ierr = nf_put_var_double(nid, id_alb, phy_glo)
775#else
776      ierr = nf_put_var_real(nid, id_alb, phy_glo)
777#endif
778      IF (ierr/=nf_noerr) THEN
779        WRITE (*, *) 'writelim error with phy_alb'
780        WRITE (*, *) nf_strerror(ierr)
781      END IF
782    END IF
783
784    CALL gather(phy_rug, phy_glo)
785    IF (is_master) THEN
786#ifdef NC_DOUBLE
787      ierr = nf_put_var_double(nid, id_rug, phy_glo)
788#else
789      ierr = nf_put_var_real(nid, id_rug, phy_glo)
790#endif
791      IF (ierr/=nf_noerr) THEN
792        WRITE (*, *) 'writelim error with phy_rug'
793        WRITE (*, *) nf_strerror(ierr)
794      END IF
795    END IF
796
797    CALL gather(phy_fter, phy_glo)
798    IF (is_master) THEN
799#ifdef NC_DOUBLE
800      ierr = nf_put_var_double(nid, id_fter, phy_glo)
801#else
802      ierr = nf_put_var_real(nid, id_fter, phy_glo)
803#endif
804      IF (ierr/=nf_noerr) THEN
805        WRITE (*, *) 'writelim error with phy_fter'
806        WRITE (*, *) nf_strerror(ierr)
807      END IF
808    END IF
809
810    CALL gather(phy_foce, phy_glo)
811    IF (is_master) THEN
812#ifdef NC_DOUBLE
813      ierr = nf_put_var_double(nid, id_foce, phy_glo)
814#else
815      ierr = nf_put_var_real(nid, id_foce, phy_glo)
816#endif
817      IF (ierr/=nf_noerr) THEN
818        WRITE (*, *) 'writelim error with phy_foce'
819        WRITE (*, *) nf_strerror(ierr)
820      END IF
821    END IF
822
823    CALL gather(phy_fsic, phy_glo)
824    IF (is_master) THEN
825#ifdef NC_DOUBLE
826      ierr = nf_put_var_double(nid, id_fsic, phy_glo)
827#else
828      ierr = nf_put_var_real(nid, id_fsic, phy_glo)
829#endif
830      IF (ierr/=nf_noerr) THEN
831        WRITE (*, *) 'writelim error with phy_fsic'
832        WRITE (*, *) nf_strerror(ierr)
833      END IF
834    END IF
835
836    CALL gather(phy_flic, phy_glo)
837    IF (is_master) THEN
838#ifdef NC_DOUBLE
839      ierr = nf_put_var_double(nid, id_flic, phy_glo)
840#else
841      ierr = nf_put_var_real(nid, id_flic, phy_glo)
842#endif
843      IF (ierr/=nf_noerr) THEN
844        WRITE (*, *) 'writelim error with phy_flic'
845        WRITE (*, *) nf_strerror(ierr)
846      END IF
847    END IF
848
849    ! close file:
850    IF (is_master) THEN
851      ierr = nf_close(nid)
852    END IF
853
854  END SUBROUTINE writelim
855
856  ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
857
858  SUBROUTINE profil_sst(nlon, rlatd, type_profil, phy_sst)
859    USE dimphy
860    USE phys_cal_mod , ONLY: year_len
861    IMPLICIT NONE
862
863    INTEGER nlon, type_profil, i, k, j
864    REAL :: rlatd(nlon), phy_sst(nlon, year_len)
865    INTEGER imn, imx, amn, amx, kmn, kmx
866    INTEGER p, pplus, nlat_max
867    PARAMETER (nlat_max=72)
868    REAL x_anom_sst(nlat_max)
869    CHARACTER (LEN=20) :: modname='profil_sst'
870    CHARACTER (LEN=80) :: abort_message
871
872    IF (klon/=nlon) THEN
873       abort_message='probleme de dimensions dans profil_sst'
874       CALL abort_physic(modname,abort_message,1)
875    ENDIF
876    WRITE (*, *) ' profil_sst: type_profil=', type_profil
877    DO i = 1, year_len
878      ! phy_sst(:,i) = 260.+50.*cos(rlatd(:))**2
879
880      ! Rajout fbrlmd
881
882      IF (type_profil==1) THEN
883        ! Méthode 1 "Control" faible plateau à l'Equateur
884        DO j = 1, klon
885          phy_sst(j, i) = 273. + 27.*(1-sin(1.5*rlatd(j))**2)
886          ! PI/3=1.047197551
887          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
888            phy_sst(j, i) = 273.
889          END IF
890        END DO
891      END IF
892      IF (type_profil==2) THEN
893        ! Méthode 2 "Flat" fort plateau à l'Equateur
894        DO j = 1, klon
895          phy_sst(j, i) = 273. + 27.*(1-sin(1.5*rlatd(j))**4)
896          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
897            phy_sst(j, i) = 273.
898          END IF
899        END DO
900      END IF
901
902
903      IF (type_profil==3) THEN
904        ! Méthode 3 "Qobs" plateau réel à l'Equateur
905        DO j = 1, klon
906          phy_sst(j, i) = 273. + 0.5*27.*(2-sin(1.5*rlatd(j))**2-sin(1.5* &
907            rlatd(j))**4)
908          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
909            phy_sst(j, i) = 273.
910          END IF
911        END DO
912      END IF
913
914      IF (type_profil==4) THEN
915        ! Méthode 4 : Méthode 3 + SST+2 "Qobs" plateau réel à l'Equateur
916        DO j = 1, klon
917          phy_sst(j, i) = 273. + 0.5*29.*(2-sin(1.5*rlatd(j))**2-sin(1.5* &
918            rlatd(j))**4)
919          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
920            phy_sst(j, i) = 273.
921          END IF
922        END DO
923      END IF
924
925      IF (type_profil==5) THEN
926        ! Méthode 5 : Méthode 3 + +2K "Qobs" plateau réel à l'Equateur
927        DO j = 1, klon
928          phy_sst(j, i) = 273. + 2. + 0.5*27.*(2-sin(1.5*rlatd(j))**2-sin(1.5 &
929            *rlatd(j))**4)
930          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
931            phy_sst(j, i) = 273. + 2.
932          END IF
933
934        END DO
935      END IF
936
937      IF (type_profil==6) THEN
938        ! Méthode 6 "cst" valeur constante de SST
939        DO j = 1, klon
940          phy_sst(j, i) = 288.
941        END DO
942      END IF
943
944
945      IF (type_profil==7) THEN
946        ! Méthode 7 "cst" valeur constante de SST +2
947        DO j = 1, klon
948          phy_sst(j, i) = 288. + 2.
949        END DO
950      END IF
951
952      p = 0
953      IF (type_profil==8) THEN
954        ! Méthode 8 profil anomalies SST du modèle couplé AR4
955        DO j = 1, klon
956          IF (rlatd(j)==rlatd(j-1)) THEN
957            phy_sst(j, i) = 273. + x_anom_sst(pplus) + &
958              0.5*27.*(2-sin(1.5*rlatd(j))**2-sin(1.5*rlatd(j))**4)
959            IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
960              phy_sst(j, i) = 273. + x_anom_sst(pplus)
961            END IF
962          ELSE
963            p = p + 1
964            pplus = 73 - p
965            phy_sst(j, i) = 273. + x_anom_sst(pplus) + &
966              0.5*27.*(2-sin(1.5*rlatd(j))**2-sin(1.5*rlatd(j))**4)
967            IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
968              phy_sst(j, i) = 273. + x_anom_sst(pplus)
969            END IF
970            WRITE (*, *) rlatd(j), x_anom_sst(pplus), phy_sst(j, i)
971          END IF
972        END DO
973      END IF
974
975      IF (type_profil==9) THEN
976        ! Méthode 5 : Méthode 3 + -2K "Qobs" plateau réel à l'Equateur
977        DO j = 1, klon
978          phy_sst(j, i) = 273. - 2. + 0.5*27.*(2-sin(1.5*rlatd(j))**2-sin(1.5 &
979            *rlatd(j))**4)
980          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
981            phy_sst(j, i) = 273. - 2.
982          END IF
983        END DO
984      END IF
985
986
987      IF (type_profil==10) THEN
988        ! Méthode 10 : Méthode 3 + +4K "Qobs" plateau réel à l'Equateur
989        DO j = 1, klon
990          phy_sst(j, i) = 273. + 4. + 0.5*27.*(2-sin(1.5*rlatd(j))**2-sin(1.5 &
991            *rlatd(j))**4)
992          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
993            phy_sst(j, i) = 273. + 4.
994          END IF
995        END DO
996      END IF
997
998      IF (type_profil==11) THEN
999        ! Méthode 11 : Méthode 3 + 4CO2 "Qobs" plateau réel à l'Equateur
1000        DO j = 1, klon
1001          phy_sst(j, i) = 273. + 0.5*27.*(2-sin(1.5*rlatd(j))**2-sin(1.5* &
1002            rlatd(j))**4)
1003          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
1004            phy_sst(j, i) = 273.
1005          END IF
1006        END DO
1007      END IF
1008
1009      IF (type_profil==12) THEN
1010        ! Méthode 12 : Méthode 10 + 4CO2 "Qobs" plateau réel à l'Equateur
1011        DO j = 1, klon
1012          phy_sst(j, i) = 273. + 4. + 0.5*27.*(2-sin(1.5*rlatd(j))**2-sin(1.5 &
1013            *rlatd(j))**4)
1014          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
1015            phy_sst(j, i) = 273. + 4.
1016          END IF
1017        END DO
1018      END IF
1019
1020      IF (type_profil==13) THEN
1021        ! Méthode 13 "Qmax" plateau réel à l'Equateur augmenté !
1022        DO j = 1, klon
1023          phy_sst(j, i) = 273. + 0.5*29.*(2-sin(1.5*rlatd(j))**2-sin(1.5* &
1024            rlatd(j))**4)
1025          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
1026            phy_sst(j, i) = 273.
1027          END IF
1028        END DO
1029      END IF
1030
1031      IF (type_profil==14) THEN
1032        ! Méthode 13 "Qmax2K" plateau réel à l'Equateur augmenté +2K !
1033        DO j = 1, klon
1034          phy_sst(j, i) = 273. + 2. + 0.5*29.*(2-sin(1.5*rlatd(j))**2-sin(1.5 &
1035            *rlatd(j))**4)
1036          IF ((rlatd(j)>1.0471975) .OR. (rlatd(j)<-1.0471975)) THEN
1037            phy_sst(j, i) = 273.
1038          END IF
1039        END DO
1040      END IF
1041
1042      if (type_profil.EQ.20) then
1043      print*,'Profile SST 20'
1044!     Méthode 13 "Qmax2K" plateau réel �|  l'Equateur augmenté +2K
1045
1046      do j=1,klon
1047        phy_sst(j,i)=248.+55.*(1-sin(rlatd(j))**2)
1048      enddo
1049      endif
1050
1051      if (type_profil.EQ.21) then
1052      print*,'Profile SST 21'
1053!     Méthode 13 "Qmax2K" plateau réel �|  l'Equateur augmenté +2K
1054      do j=1,klon
1055        phy_sst(j,i)=252.+55.*(1-sin(rlatd(j))**2)
1056      enddo
1057      endif
1058
1059
1060
1061    END DO
1062
1063    ! IM beg : verif profil SST: phy_sst
1064    amn = min(phy_sst(1,1), 1000.)
1065    amx = max(phy_sst(1,1), -1000.)
1066    imn = 1
1067    kmn = 1
1068    imx = 1
1069    kmx = 1
1070    DO k = 1, year_len
1071      DO i = 2, nlon
1072        IF (phy_sst(i,k)<amn) THEN
1073          amn = phy_sst(i, k)
1074          imn = i
1075          kmn = k
1076        END IF
1077        IF (phy_sst(i,k)>amx) THEN
1078          amx = phy_sst(i, k)
1079          imx = i
1080          kmx = k
1081        END IF
1082      END DO
1083    END DO
1084
1085    PRINT *, 'profil_sst: imn, kmn, phy_sst(imn,kmn) ', imn, kmn, amn
1086    PRINT *, 'profil_sst: imx, kmx, phy_sst(imx,kmx) ', imx, kmx, amx
1087    ! IM end : verif profil SST: phy_sst
1088
1089    RETURN
1090  END SUBROUTINE profil_sst
1091
1092END MODULE phyaqua_mod
Note: See TracBrowser for help on using the repository browser.