source: LMDZ6/trunk/libf/phylmdiso/phyaqua_mod.F90 @ 4738

Last change on this file since 4738 was 4619, checked in by yann meurdesoif, 17 months ago

Suppress usage of preprocessing key CPP_XIOS.
Wrapper file is used to suppress XIOS symbol when xios is not linked and not used (-io ioipsl)
The CPP_XIOS key is replaced in model by "using_xios" boolean variable to switch between IOIPSL or XIOS output.

YM

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.