source: LMDZ6/trunk/libf/phylmd/iostart.f90 @ 5456

Last change on this file since 5456 was 5268, checked in by abarral, 2 months ago

.f90 <-> .F90 depending on cpp key use

  • 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:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.2 KB
RevLine 
[1001]1MODULE iostart
[5084]2
[1001]3PRIVATE
4    INTEGER,SAVE :: nid_start
5    INTEGER,SAVE :: nid_restart
6   
[1403]7    INTEGER,SAVE :: idim1,idim2,idim3,idim4
[1001]8    INTEGER,PARAMETER :: length=100
9   
10    INTERFACE get_field
11      MODULE PROCEDURE Get_field_r1,Get_field_r2,Get_field_r3
12    END INTERFACE get_field
13   
14    INTERFACE get_var
15      MODULE PROCEDURE get_var_r0,Get_var_r1,Get_var_r2,Get_var_r3
16    END INTERFACE get_var
17
18    INTERFACE put_field
19      MODULE PROCEDURE put_field_r1,put_field_r2,put_field_r3
20    END INTERFACE put_field
21
22    INTERFACE put_var
23      MODULE PROCEDURE put_var_r0,put_var_r1,put_var_r2,put_var_r3
24    END INTERFACE put_var
25
26    PUBLIC get_field,get_var,put_field,put_var
[3506]27    PUBLIC Open_startphy,close_startphy,open_restartphy,close_restartphy, enddef_restartphy
[1001]28   
29CONTAINS
30
31  SUBROUTINE Open_startphy(filename)
[5084]32  USE netcdf
[1001]33  USE mod_phys_lmdz_para
34  IMPLICIT NONE
35    CHARACTER(LEN=*) :: filename
36    INTEGER          :: ierr
37
38    IF (is_mpi_root .AND. is_omp_root) THEN
39      ierr = NF90_OPEN (filename, NF90_NOWRITE,nid_start)
[5084]40      IF (ierr.NE.NF90_NOERR) THEN
[1001]41        write(6,*)' Pb d''ouverture du fichier '//filename
42        write(6,*)' ierr = ', ierr
[2311]43        CALL abort_physic("", "", 1)
[1001]44      ENDIF
45    ENDIF
46   
47  END SUBROUTINE Open_startphy
48
49  SUBROUTINE Close_startphy
[5084]50  USE netcdf
[1001]51  USE mod_phys_lmdz_para
52  IMPLICIT NONE
53    INTEGER          :: ierr
54
55    IF (is_mpi_root .AND. is_omp_root) THEN
56        ierr = NF90_CLOSE (nid_start)
57    ENDIF
58
59  END SUBROUTINE close_startphy
60
61
62  FUNCTION Inquire_Field(Field_name)
[5084]63  USE netcdf
[1001]64  USE mod_phys_lmdz_para
65  IMPLICIT NONE
66    CHARACTER(LEN=*) :: Field_name
67    LOGICAL :: inquire_field
68    INTEGER :: varid
69    INTEGER :: ierr
70   
71    IF (is_mpi_root .AND. is_omp_root) THEN
72      ierr=NF90_INQ_VARID(nid_start,Field_name,varid)
73      IF (ierr==NF90_NOERR) THEN
74        Inquire_field=.TRUE.
75      ELSE
76        Inquire_field=.FALSE.
77      ENDIF
78    ENDIF
79
80    CALL bcast(Inquire_field)
81
82  END FUNCTION Inquire_Field
83 
84 
85  SUBROUTINE Get_Field_r1(field_name,field,found)
86  IMPLICIT NONE
87    CHARACTER(LEN=*),INTENT(IN)    :: Field_name
88    REAL,INTENT(INOUT)               :: Field(:)
89    LOGICAL,INTENT(OUT),OPTIONAL   :: found
90
[3070]91    CALL Get_field_rgen(field_name,field,1,found)
[1001]92     
93  END SUBROUTINE Get_Field_r1
94 
95  SUBROUTINE Get_Field_r2(field_name,field,found)
96  IMPLICIT NONE
97    CHARACTER(LEN=*),INTENT(IN)    :: Field_name
98    REAL,INTENT(INOUT)               :: Field(:,:)
99    LOGICAL,INTENT(OUT),OPTIONAL   :: found
100
[3070]101    CALL Get_field_rgen(field_name,field,size(field,2),found)
[1001]102
103     
104  END SUBROUTINE Get_Field_r2
105 
106  SUBROUTINE Get_Field_r3(field_name,field,found)
107  IMPLICIT NONE
108    CHARACTER(LEN=*),INTENT(IN)    :: Field_name
109    REAL,INTENT(INOUT)               :: Field(:,:,:)
110    LOGICAL,INTENT(OUT),OPTIONAL   :: found
111
[3070]112    CALL Get_field_rgen(field_name,field,size(field,2)*size(field,3),found)
[1001]113     
114  END SUBROUTINE Get_Field_r3
115 
116  SUBROUTINE Get_field_rgen(field_name,field,field_size,found)
[5084]117  USE netcdf
[1001]118  USE dimphy
[3435]119  USE geometry_mod
[1001]120  USE mod_grid_phy_lmdz
121  USE mod_phys_lmdz_para
122  IMPLICIT NONE
123    CHARACTER(LEN=*) :: Field_name
124    INTEGER          :: field_size
125    REAL             :: field(klon,field_size)
126    LOGICAL,OPTIONAL :: found
127   
[3465]128    REAL,ALLOCATABLE    :: field_glo(:,:)
129    REAL,ALLOCATABLE    :: field_glo_tmp(:,:)
130    INTEGER,ALLOCATABLE :: ind_cell_glo_glo(:)
[1001]131    LOGICAL :: tmp_found
132    INTEGER :: varid
[3435]133    INTEGER :: ierr,i
134
[3465]135    IF (is_master) THEN
136      ALLOCATE(ind_cell_glo_glo(klon_glo))
137      ALLOCATE(field_glo(klon_glo,field_size))
138      ALLOCATE(field_glo_tmp(klon_glo,field_size))
139    ELSE
140      ALLOCATE(ind_cell_glo_glo(0))
141      ALLOCATE(field_glo(0,0))
142    ENDIF
143   
[3435]144    CALL gather(ind_cell_glo,ind_cell_glo_glo)
[1001]145   
[3435]146    IF (is_master) THEN
[1001]147 
148      ierr=NF90_INQ_VARID(nid_start,Field_name,varid)
149     
150      IF (ierr==NF90_NOERR) THEN
[3435]151        CALL body(field_glo_tmp)
[1001]152        tmp_found=.TRUE.
153      ELSE
154        tmp_found=.FALSE.
155      ENDIF
156   
157    ENDIF
158   
159    CALL bcast(tmp_found)
160
161    IF (tmp_found) THEN
[3435]162      IF (is_master) THEN 
163        DO i=1,klon_glo
164         field_glo(i,:)=field_glo_tmp(ind_cell_glo_glo(i),:)
165        ENDDO
166      ENDIF
[1001]167      CALL scatter(field_glo,field)
168    ENDIF
169   
170    IF (PRESENT(found)) THEN
171      found=tmp_found
172    ELSE
173      IF (.NOT. tmp_found) THEN
174        PRINT*, 'phyetat0: Le champ <'//field_name//'> est absent'
[2311]175        call abort_physic("", "", 1)
[1001]176      ENDIF
177    ENDIF
178 
179   
180    CONTAINS
181     
182     SUBROUTINE body(field_glo)
183       REAL :: field_glo(klon_glo*field_size)
184         ierr=NF90_GET_VAR(nid_start,varid,field_glo)
185         IF (ierr/=NF90_NOERR) THEN
[1619]186           ! La variable exist dans le fichier mais la lecture a echouee.
[1001]187           PRINT*, 'phyetat0: Lecture echouee pour <'//field_name//'>'
[1619]188
189           IF (field_name=='CLWCON' .OR. field_name=='RNEBCON' .OR. field_name=='RATQS') THEN
190              ! Essaye de lire le variable sur surface uniqument, comme fait avant
191              field_glo(:)=0.
192              ierr=NF90_GET_VAR(nid_start,varid,field_glo(1:klon_glo))
193              IF (ierr/=NF90_NOERR) THEN
194                 PRINT*, 'phyetat0: Lecture echouee aussi en 2D pour <'//field_name//'>'
[2311]195                 call abort_physic("", "", 1)
[1619]196              ELSE
197                 PRINT*, 'phyetat0: La variable <'//field_name//'> lu sur surface seulement'!, selon ancien format, le reste mis a zero'
198              END IF
199           ELSE
[2311]200              call abort_physic("", "", 1)
[1619]201           ENDIF
[1001]202         ENDIF
203
204     END SUBROUTINE body
205
206  END SUBROUTINE Get_field_rgen
207 
208
209  SUBROUTINE get_var_r0(var_name,var,found)
210  IMPLICIT NONE 
211    CHARACTER(LEN=*),INTENT(IN)  :: var_name
212    REAL,INTENT(INOUT)             :: var
213    LOGICAL,OPTIONAL,INTENT(OUT) :: found
214
215    REAL                         :: varout(1)
216   
[3070]217    CALL Get_var_rgen(var_name,varout,size(varout),found)
[1001]218    var=varout(1)
219 
220  END SUBROUTINE get_var_r0
221
222  SUBROUTINE get_var_r1(var_name,var,found)
223  IMPLICIT NONE 
224    CHARACTER(LEN=*),INTENT(IN)  :: var_name
225    REAL,INTENT(INOUT)             :: var(:)
226    LOGICAL,OPTIONAL,INTENT(OUT) :: found
227   
[3070]228    CALL Get_var_rgen(var_name,var,size(var),found)
[1001]229 
230  END SUBROUTINE get_var_r1
231
232  SUBROUTINE get_var_r2(var_name,var,found)
233  IMPLICIT NONE 
234    CHARACTER(LEN=*),INTENT(IN)  :: var_name
235    REAL,INTENT(OUT)             :: var(:,:)
236    LOGICAL,OPTIONAL,INTENT(OUT) :: found
237   
[3070]238    CALL Get_var_rgen(var_name,var,size(var),found)
[1001]239 
240  END SUBROUTINE get_var_r2
241
242  SUBROUTINE get_var_r3(var_name,var,found)
243  IMPLICIT NONE 
244    CHARACTER(LEN=*),INTENT(IN)  :: var_name
245    REAL,INTENT(INOUT)             :: var(:,:,:)
246    LOGICAL,OPTIONAL,INTENT(OUT) :: found
247   
[3070]248    CALL Get_var_rgen(var_name,var,size(var),found)
[1001]249 
250  END SUBROUTINE get_var_r3
251
252  SUBROUTINE Get_var_rgen(var_name,var,var_size,found)
[5084]253  USE netcdf
[1001]254  USE dimphy
255  USE mod_grid_phy_lmdz
256  USE mod_phys_lmdz_para
257  IMPLICIT NONE
258    CHARACTER(LEN=*) :: var_name
259    INTEGER          :: var_size
260    REAL             :: var(var_size)
261    LOGICAL,OPTIONAL :: found
262   
263    LOGICAL :: tmp_found
264    INTEGER :: varid
265    INTEGER :: ierr
266   
267    IF (is_mpi_root .AND. is_omp_root) THEN
268 
269      ierr=NF90_INQ_VARID(nid_start,var_name,varid)
270     
271      IF (ierr==NF90_NOERR) THEN
272        ierr=NF90_GET_VAR(nid_start,varid,var)
273        IF (ierr/=NF90_NOERR) THEN
274          PRINT*, 'phyetat0: Lecture echouee pour <'//var_name//'>'
[2311]275          call abort_physic("", "", 1)
[1001]276        ENDIF
277        tmp_found=.TRUE.
278      ELSE
279        tmp_found=.FALSE.
280      ENDIF
281   
282    ENDIF
283   
284    CALL bcast(tmp_found)
285
286    IF (tmp_found) THEN
287      CALL bcast(var)
288    ENDIF
289   
290    IF (PRESENT(found)) THEN
291      found=tmp_found
292    ELSE
293      IF (.NOT. tmp_found) THEN
294        PRINT*, 'phyetat0: La variable champ <'//var_name//'> est absente'
[2311]295        call abort_physic("", "", 1)
[1001]296      ENDIF
297    ENDIF
298
299  END SUBROUTINE Get_var_rgen
300
301
302  SUBROUTINE open_restartphy(filename)
[5084]303  USE netcdf
[3401]304  USE mod_phys_lmdz_para, ONLY: is_master
305  USE mod_grid_phy_lmdz, ONLY: klon_glo
306  USE dimphy, ONLY: klev, klevp1
307  USE print_control_mod, ONLY: lunout
[1001]308  IMPLICIT NONE
309    CHARACTER(LEN=*),INTENT(IN) :: filename
310    INTEGER                     :: ierr
311   
[3401]312    IF (is_master) THEN
313      ierr = NF90_CREATE(filename, IOR(NF90_CLOBBER,NF90_64BIT_OFFSET), &
314                          nid_restart)
[1001]315      IF (ierr/=NF90_NOERR) THEN
[3401]316        write(lunout,*)'open_restartphy: problem creating file '//trim(filename)
317        write(lunout,*)trim(nf90_strerror(ierr))
318        CALL abort_physic("open_restartphy", trim(nf90_strerror(ierr)), 1)
[1001]319      ENDIF
320
321      ierr = NF90_PUT_ATT (nid_restart, NF90_GLOBAL, "title","Fichier redemmarage physique")
322
323      ierr = NF90_DEF_DIM (nid_restart, "index", length, idim1)
324      ierr = NF90_DEF_DIM (nid_restart, "points_physiques", klon_glo, idim2)
325      ierr = NF90_DEF_DIM (nid_restart, "horizon_vertical", klon_glo*klev, idim3)
[1403]326      ierr = NF90_DEF_DIM (nid_restart, "horizon_klevp1", klon_glo*klevp1, idim4)
[1001]327
[3506]328!      ierr = NF90_ENDDEF(nid_restart)
[1001]329    ENDIF
330
331  END SUBROUTINE open_restartphy
332 
[3506]333  SUBROUTINE enddef_restartphy
[5084]334  USE netcdf
[3506]335  USE mod_phys_lmdz_para
336  IMPLICIT NONE
337    INTEGER          :: ierr
338
339    IF (is_master) ierr = NF90_ENDDEF(nid_restart)
340 
341  END SUBROUTINE enddef_restartphy
342
[1001]343  SUBROUTINE close_restartphy
[5084]344  USE netcdf
[1001]345  USE mod_phys_lmdz_para
346  IMPLICIT NONE
347    INTEGER          :: ierr
348
[3506]349    IF (is_master) ierr = NF90_CLOSE (nid_restart)
[1001]350 
351  END SUBROUTINE close_restartphy
352
353 
[3506]354  SUBROUTINE put_field_r1(pass, field_name,title,field)
[1001]355  IMPLICIT NONE
[3506]356  INTEGER, INTENT(IN)            :: pass
[1001]357  CHARACTER(LEN=*),INTENT(IN)    :: field_name
358  CHARACTER(LEN=*),INTENT(IN)    :: title
359  REAL,INTENT(IN)                :: field(:)
[3506]360    CALL put_field_rgen(pass, field_name,title,field,1)
[1001]361 
362  END SUBROUTINE put_field_r1
363
[3506]364  SUBROUTINE put_field_r2(pass, field_name,title,field)
[1001]365  IMPLICIT NONE
[3506]366  INTEGER, INTENT(IN)            :: pass
[1001]367  CHARACTER(LEN=*),INTENT(IN)    :: field_name
368  CHARACTER(LEN=*),INTENT(IN)    :: title
369  REAL,INTENT(IN)                :: field(:,:)
370 
[3506]371    CALL put_field_rgen(pass, field_name,title,field,size(field,2))
[1001]372 
373  END SUBROUTINE put_field_r2
374
[3506]375  SUBROUTINE put_field_r3(pass, field_name,title,field)
[1001]376  IMPLICIT NONE
[3506]377  INTEGER, INTENT(IN)            :: pass
[1001]378  CHARACTER(LEN=*),INTENT(IN)    :: field_name
379  CHARACTER(LEN=*),INTENT(IN)    :: title
380  REAL,INTENT(IN)                :: field(:,:,:)
381 
[3506]382    CALL put_field_rgen(pass, field_name,title,field,size(field,2)*size(field,3))
[1001]383 
384  END SUBROUTINE put_field_r3
385 
[3506]386  SUBROUTINE put_field_rgen(pass, field_name,title,field,field_size)
[5084]387  USE netcdf
[1001]388  USE dimphy
[3435]389  USE geometry_mod
[1001]390  USE mod_grid_phy_lmdz
391  USE mod_phys_lmdz_para
[5249]392  USE lmdz_cppkeys_wrapper, ONLY: nf90_format
[1001]393  IMPLICIT NONE
[3506]394  INTEGER, INTENT(IN)            :: pass
[1001]395  CHARACTER(LEN=*),INTENT(IN)    :: field_name
396  CHARACTER(LEN=*),INTENT(IN)    :: title
397  INTEGER,INTENT(IN)             :: field_size
398  REAL,INTENT(IN)                :: field(klon,field_size)
399 
[3506]400!  REAL                           :: field_glo(klon_glo,field_size)
401!  REAL                           :: field_glo_tmp(klon_glo,field_size)
402  REAL ,ALLOCATABLE              :: field_glo(:,:)
403  REAL ,ALLOCATABLE              :: field_glo_tmp(:,:)
404  INTEGER,ALLOCATABLE            :: ind_cell_glo_glo(:)
405!  INTEGER                        :: ind_cell_glo_glo(klon_glo)
[3435]406  INTEGER                        :: ierr,i
[1001]407  INTEGER                        :: nvarid
408  INTEGER                        :: idim
409   
[3506]410! first pass : definition   
411  IF (pass==1) THEN
[1001]412   
[3435]413    IF (is_master) THEN
[1403]414
[1001]415      IF (field_size==1) THEN
416        idim=idim2
417      ELSE IF (field_size==klev) THEN
418        idim=idim3
[1403]419      ELSE IF (field_size==klevp1) THEN
420        idim=idim4
[1001]421      ELSE
422        PRINT *, "erreur phyredem : probleme de dimension"
[2311]423        CALL abort_physic("", "", 1)
[1001]424      ENDIF
425         
[3506]426!      ierr = NF90_REDEF (nid_restart)
[5249]427      ierr = NF90_DEF_VAR (nid_restart, field_name, nf90_format,(/ idim /),nvarid)
[1001]428      IF (LEN_TRIM(title) > 0) ierr = NF90_PUT_ATT (nid_restart,nvarid,"title", title)
[3506]429!      ierr = NF90_ENDDEF(nid_restart)
430     ENDIF
431
432! second pass : write     
433   ELSE IF (pass==2) THEN
[1001]434   
[3506]435     IF (is_master) THEN
436       ALLOCATE(ind_cell_glo_glo(klon_glo))
437       ALLOCATE(field_glo(klon_glo,field_size))
438       ALLOCATE(field_glo_tmp(klon_glo,field_size))
439     ELSE
440       ALLOCATE(ind_cell_glo_glo(0))
[3508]441       ALLOCATE(field_glo_tmp(0,0))
[3506]442     ENDIF
443     
444     CALL gather(ind_cell_glo,ind_cell_glo_glo)
445
446     CALL gather(field,field_glo_tmp)
447   
448     IF (is_master) THEN
449
450       DO i=1,klon_glo
451         field_glo(ind_cell_glo_glo(i),:)=field_glo_tmp(i,:)
452       ENDDO
453
454       ierr = NF90_INQ_VARID(nid_restart, field_name, nvarid)
455       ierr = NF90_PUT_VAR(nid_restart,nvarid,RESHAPE(field_glo,(/klon_glo*field_size/)))
456      ENDIF
457   ENDIF
458   
459 END SUBROUTINE put_field_rgen 
[1001]460 
[3506]461
462 SUBROUTINE put_var_r0(pass, var_name,title,var)
[1001]463   IMPLICIT NONE
[3506]464     INTEGER, INTENT(IN)            :: pass
[1001]465     CHARACTER(LEN=*),INTENT(IN) :: var_name
466     CHARACTER(LEN=*),INTENT(IN) :: title
467     REAL,INTENT(IN)             :: var
468     REAL                        :: varin(1)
469     
470     varin(1)=var
471     
[3506]472     CALL put_var_rgen(pass, var_name,title,varin,size(varin))
[1001]473
474  END SUBROUTINE put_var_r0
475
476
[3506]477   SUBROUTINE put_var_r1(pass, var_name,title,var)
[1001]478   IMPLICIT NONE
[3506]479     INTEGER, INTENT(IN)            :: pass
[1001]480     CHARACTER(LEN=*),INTENT(IN) :: var_name
481     CHARACTER(LEN=*),INTENT(IN) :: title
482     REAL,INTENT(IN)             :: var(:)
483     
[3506]484     CALL put_var_rgen(pass, var_name,title,var,size(var))
[1001]485
486  END SUBROUTINE put_var_r1
487 
[3506]488  SUBROUTINE put_var_r2(pass, var_name,title,var)
[1001]489   IMPLICIT NONE
[3506]490     INTEGER, INTENT(IN)            :: pass
[1001]491     CHARACTER(LEN=*),INTENT(IN) :: var_name
492     CHARACTER(LEN=*),INTENT(IN) :: title
493     REAL,INTENT(IN)             :: var(:,:)
494     
[3506]495     CALL put_var_rgen(pass, var_name,title,var,size(var))
[1001]496
497  END SUBROUTINE put_var_r2     
498 
[3506]499  SUBROUTINE put_var_r3(pass, var_name,title,var)
[1001]500   IMPLICIT NONE
[3506]501     INTEGER, INTENT(IN)            :: pass
[1001]502     CHARACTER(LEN=*),INTENT(IN) :: var_name
503     CHARACTER(LEN=*),INTENT(IN) :: title
504     REAL,INTENT(IN)             :: var(:,:,:)
505     
[3506]506     CALL put_var_rgen(pass, var_name,title,var,size(var))
[1001]507
508  END SUBROUTINE put_var_r3
509
[3506]510  SUBROUTINE put_var_rgen(pass, var_name,title,var,var_size)
[5084]511  USE netcdf
[1001]512  USE dimphy
513  USE mod_phys_lmdz_para
[5249]514  USE lmdz_cppkeys_wrapper, ONLY: nf90_format
[1001]515  IMPLICIT NONE
[3506]516    INTEGER, INTENT(IN)         :: pass
517    CHARACTER(LEN=*),INTENT(IN) :: var_name
518    CHARACTER(LEN=*),INTENT(IN) :: title
519    INTEGER,INTENT(IN)          :: var_size
520    REAL,INTENT(IN)             :: var(var_size)
521   
522    INTEGER :: ierr
523    INTEGER :: nvarid
[1001]524         
[3506]525    IF (is_master) THEN
[1403]526
[1001]527      IF (var_size/=length) THEN
528        PRINT *, "erreur phyredem : probleme de dimension"
[2311]529        call abort_physic("", "", 1)
[1001]530      ENDIF
531
[3506]532     ! first pass : definition   
533      IF (pass==1) THEN
534       
535!      ierr = NF90_REDEF (nid_restart)
[5249]536        ierr = NF90_DEF_VAR (nid_restart, var_name, nf90_format,(/ idim1 /),nvarid)
[3506]537        IF (LEN_TRIM(title)>0) ierr = NF90_PUT_ATT (nid_restart,nvarid,"title", title)
538!      ierr = NF90_ENDDEF(nid_restart)
[1001]539
[3506]540    ! second pass : write     
541      ELSE IF (pass==2) THEN
542        ierr = NF90_INQ_VARID(nid_restart, var_name, nvarid)
543        ierr = NF90_PUT_VAR(nid_restart,nvarid,var)
544      ENDIF
[1001]545    ENDIF
546   
547  END SUBROUTINE put_var_rgen     
548   
549END MODULE iostart
Note: See TracBrowser for help on using the repository browser.