source: LMDZ6/trunk/libf/phylmd/phyaqua_mod.F90 @ 5171

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

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

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