source: codes/icosagcm/devel/src/output/xios_mod.F90 @ 922

Last change on this file since 922 was 922, checked in by dubos, 5 years ago

devel :fix bug in xios_read_field introduced by [880]

File size: 12.0 KB
RevLine 
[171]1MODULE xios_mod
[880]2 
[171]3#ifdef CPP_USING_XIOS
[880]4  USE xios
[171]5#endif
6
[880]7  USE prec, ONLY : rstd
8  USE field_mod, ONLY : t_field, field_T, field_U, field_Z
9  USE domain_mod, ONLY : t_domain, t_cellset, domain, ndomain, mesh_loc
[905]10  USE grid_param, ONLY : grid_type, grid_unst, grid_ico
[880]11  IMPLICIT NONE   
12  PRIVATE
13  SAVE
[186]14
[880]15  LOGICAL :: using_xios
[171]16
[880]17  INTEGER :: ncell_i, ncell_v, ncell_e
18!$OMP THREADPRIVATE(ncell_i, ncell_v, ncell_e)
[482]19
[880]20  PUBLIC :: using_xios, xios_init, &
21       xios_init_write_field,  xios_write_field_finalize, &
22       xios_write_field, xios_read_field
23
[482]24#ifdef CPP_USING_XIOS
[880]25
26  PUBLIC :: xios_timestep,    & 
27       xios_set_file_attr, xios_set_fieldgroup_attr, &
28       xios_set_filegroup_attr, xios_get_axis_attr, &
29       xios_send_field, xios_read_var, &
30       xios_update_calendar, xios_set_context
[171]31 
32CONTAINS
33 
34 SUBROUTINE xios_init
[880]35   USE mpipara, ONLY : comm_icosa
36   TYPE(xios_context) :: ctx_hdl
[171]37
[880]38   using_xios=.TRUE.
39   CALL xios_context_initialize("icosagcm",comm_icosa)
40   CALL xios_get_handle("icosagcm",ctx_hdl)
41   CALL xios_set_current_context(ctx_hdl)   
42
43 END SUBROUTINE xios_init
44
[171]45 SUBROUTINE xios_init_write_field
[886]46   USE disvert_mod, ONLY : presnivs
[880]47   USE time_mod, ONLY : dt, itau_out
48   USE grid_param, ONLY : llm, nqtot
49   USE mpi_mod, ONLY : MPI_INTEGER
[171]50
[880]51   TYPE(xios_context) :: ctx_hdl
52   TYPE(xios_duration)      :: dtime
53   REAL(rstd) :: lev_value(llm)
54   REAL(rstd) :: lev_valuep1(llm+1)
55   REAL(rstd) :: nq_value(nqtot)
56   INTEGER :: l, ncell, ncell_tot, displ
57   REAL(rstd),ALLOCATABLE    :: lon(:), lat(:), bounds_lon(:,:), bounds_lat(:,:)
58   INTEGER, ALLOCATABLE      :: ind_glo(:)
59   TYPE(t_domain),POINTER :: d
60   
61   !$OMP BARRIER
62   !$OMP MASTER
63   !   CALL xios_context_initialize("icosagcm",comm_icosa)
[171]64   CALL xios_get_handle("icosagcm",ctx_hdl)
65   CALL xios_set_current_context(ctx_hdl)
66   lev_value(:) = (/ (l,l=1,llm) /)     
67   lev_valuep1(:) = (/ (l,l=1,llm+1) /)     
[492]68   nq_value(:) = (/ (l,l=1,nqtot) /)     
[394]69   CALL xios_set_axis_attr("lev",n_glo=llm ,value=lev_value) ;
70   CALL xios_set_axis_attr("levp1",n_glo=llm+1 ,value=lev_valuep1) ;
[492]71   CALL xios_set_axis_attr("nq",n_glo=nqtot, value=nq_value) ;
[886]72   CALL xios_set_axis_attr("presnivs_mb",n_glo=llm, value=presnivs/100., unit="mb") ;
73
[880]74   !------------------ primal cells ------------------
75   CALL collect_bounds(6, mesh_loc%primal_own)
76   ncell_i=ncell   
[394]77   CALL xios_set_domaingroup_attr("i",ni_glo=ncell_tot, ibegin=displ, ni=ncell)
[483]78   CALL xios_set_domaingroup_attr("i", data_dim=1, type='unstructured' , nvertex=6, i_index=ind_glo)
[394]79   CALL xios_set_domaingroup_attr("i",lonvalue_1d=lon, latvalue_1d=lat, bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)
[880]80   DEALLOCATE(lon, lat, bounds_lon, bounds_lat,ind_glo) 
[171]81   
[880]82   !--------------------- dual cells ------------------
83   
84   CALL collect_bounds(3, mesh_loc%dual_own)
85   ncell_v=ncell
86   CALL xios_set_domain_attr("v",ni_glo=ncell_tot, ibegin=displ, ni=ncell)
87   CALL xios_set_domain_attr("v", data_dim=1, type='unstructured' , nvertex=3)
88   CALL xios_set_domain_attr("v",lonvalue_1d=lon, latvalue_1d=lat, bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)
[483]89   DEALLOCATE(lon, lat, bounds_lon, bounds_lat,ind_glo) 
90   
[880]91   !---------------------- edges -----------------------
[483]92   
[880]93   CALL collect_bounds(2, mesh_loc%edge_own)
94   ncell_e=ncell
[483]95   CALL xios_set_domain_attr("u",ni_glo=ncell_tot, ibegin=displ, ni=ncell)
96   CALL xios_set_domain_attr("u", data_dim=1, type='unstructured' , nvertex=2, i_index=ind_glo)
97   CALL xios_set_domain_attr("u",lonvalue_1d=lon, latvalue_1d=lat, bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)
98   DEALLOCATE(lon, lat, bounds_lon, bounds_lat,ind_glo) 
[171]99   
100   dtime%second=dt
[429]101   CALL xios_set_timestep(dtime)
102   
103   CALL xios_set_fieldgroup_attr("standard_output", freq_op=itau_out*xios_timestep, freq_offset=(itau_out-1)*xios_timestep)
[880]104   
[171]105   CALL xios_close_context_definition()
[880]106   !$OMP END MASTER
107   !$OMP BARRIER
[186]108   
[880]109 CONTAINS
110   
111   SUBROUTINE collect_bounds(nvert, cells)
112     USE mpipara, ONLY : comm_icosa, mpi_size, mpi_rank
113     INTEGER, INTENT(IN) :: nvert
114     TYPE(t_cellset)     :: cells(:)
115     INTEGER :: i, ind, n_beg, n_end, ierr, ncell_glo(0:mpi_size-1)
116     ncell = SUM(cells%ncell)
117     CALL MPI_ALLGATHER(ncell,1,MPI_INTEGER, &
118          ncell_glo,1, MPI_INTEGER, comm_icosa, ierr)
119     displ=0
120     DO i=1,mpi_rank
121        displ=displ+ncell_glo(i-1)
122     ENDDO
123     ncell_tot=sum(ncell_glo(:))
124     
125     ALLOCATE(lon(ncell), lat(ncell), ind_glo(ncell))
126     ALLOCATE(bounds_lon(nvert,ncell), bounds_lat(nvert,ncell))
127     
128     n_beg=0
129     DO ind=1,ndomain
130        n_end = n_beg + cells(ind)%ncell
131        ind_glo(n_beg+1:n_end) = cells(ind)%ind_glo(:)
132        lon(n_beg+1:n_end) = cells(ind)%lon(:)
133        lat(n_beg+1:n_end) = cells(ind)%lat(:)
134        bounds_lon(:,n_beg+1:n_end) = cells(ind)%bnds_lon(:,:)
135        bounds_lat(:,n_beg+1:n_end) = cells(ind)%bnds_lat(:,:)
136        n_beg = n_end
137     END DO
138   END SUBROUTINE collect_bounds
139   
[171]140 END SUBROUTINE xios_init_write_field
[880]141 
[171]142 SUBROUTINE xios_write_field(name,field)
143   CHARACTER(LEN=*),INTENT(IN) :: name
144   TYPE(t_field), POINTER :: field(:)
[880]145   TYPE(t_cellset), POINTER :: cells(:)
146   INTEGER :: ncells
[186]147
148!$OMP BARRIER
149!$OMP MASTER
[483]150
[880]151   SELECT CASE(field(1)%field_type)
152   CASE(field_T)
153      cells => mesh_loc%primal_own
154      ncells = ncell_i
155   CASE(field_U)
156      cells => mesh_loc%edge_own
157      ncells = ncell_e
158   CASE(field_Z)
159      cells => mesh_loc%dual_own
160      ncells = ncell_v
161   END SELECT
[483]162
[880]163   IF (field(1)%ndim>4) THEN
164      PRINT *, "xios_write_field : dimension > 4 are not supported for now"
165   ELSE
[905]166      CALL xios_write_field_gen(name, field, cells, & 
[880]167           ncells, field(1)%dim3, field(1)%dim4)
168   END IF
169   
[186]170!$OMP END MASTER
171!$OMP BARRIER
[171]172     
173 END SUBROUTINE xios_write_field
[394]174
175 SUBROUTINE xios_read_field(name,field)
176   CHARACTER(LEN=*),INTENT(IN) :: name
177   TYPE(t_field), POINTER :: field(:)
[880]178   TYPE(t_cellset), POINTER :: cells(:)
179   INTEGER :: ncells
[394]180
181!$OMP BARRIER
182!$OMP MASTER
[880]183
184   SELECT CASE(field(1)%field_type)
185   CASE(field_T)
186      cells => mesh_loc%primal_own
187      ncells = ncell_i
188   CASE(field_U)
189      cells => mesh_loc%edge_own
190      ncells = ncell_e
191   CASE(field_Z)
192      cells => mesh_loc%dual_own
193      ncells = ncell_v
194   END SELECT
195
196   IF (field(1)%ndim>4) THEN
197      PRINT *, "xios_read_field : dimension > 4 are not supported for now"
198   ELSE
199      CALL xios_read_field_hex(name, field, cells, & 
200           ncells, field(1)%dim3, field(1)%dim4)
201   END IF
[394]202   
203!$OMP END MASTER
204!$OMP BARRIER
205     
206 END SUBROUTINE xios_read_field
207
[905]208 SUBROUTINE xios_write_field_gen(name, field, cells, ncell_tot, nlev, nq)
[880]209   CHARACTER(LEN=*),INTENT(IN) :: name
210   TYPE(t_field) :: field(:)
211   TYPE(t_cellset), TARGET :: cells(:)
212   INTEGER,INTENT(IN) :: ncell_tot, nlev, nq
[905]213   REAL(rstd) :: field_tmp(ncell_tot, nlev, nq)
[880]214   TYPE(t_cellset), POINTER :: cellset
[905]215   INTEGER :: ind, n_beg, n, ij, sgn
[880]216   LOGICAL :: signed
217
218   IF(ALLOCATED(cells(1)%sgn)) THEN
219      signed=.TRUE.
220   ELSE
221      signed=.FALSE.
222      sgn=1
223   END IF
224
225   n_beg=0
226   DO ind=1,ndomain
227      cellset => cells(ind)
228      DO n=1, cellset%ncell
229         ij = cellset%ij(n)
230         IF(signed) sgn = cellset%sgn(n)
[905]231         SELECT CASE(grid_type)
232         CASE(grid_ico)
233            SELECT CASE(field(1)%ndim)
234            CASE(2)
235               field_tmp(n_beg+n,1,1) = sgn*field(ind)%rval2d(ij)
236            CASE(3)
237               field_tmp(n_beg+n,:,1) = sgn*field(ind)%rval3d(ij,:)
238            CASE(4)
239               field_tmp(n_beg+n,:,:) = sgn*field(ind)%rval4d(ij,:,:)
240            END SELECT
241         CASE(grid_unst)
242            SELECT CASE(field(1)%ndim)
243            CASE(2)
244               field_tmp(n_beg+n,1,1) = sgn*field(ind)%rval2d(ij)
245            CASE(3)
246               field_tmp(n_beg+n,:,1) = sgn*field(ind)%rval3d(:,ij)
247            CASE(4)
248               field_tmp(n_beg+n,:,:) = sgn*field(ind)%rval4d(:,ij,:)
249            END SELECT
[880]250         END SELECT
251      END DO
[905]252      n_beg = n_beg + cellset%ncell
[880]253   END DO
254   CALL xios_send_field(name,field_tmp) 
[905]255   
256 END SUBROUTINE xios_write_field_gen
[880]257
258SUBROUTINE xios_read_field_hex(name, field, cells, ncell_tot, nlev, nq)
[171]259   CHARACTER(LEN=*),INTENT(IN) :: name
[880]260   TYPE(t_field) :: field(:)
261   TYPE(t_cellset), TARGET :: cells(:)
262   INTEGER,INTENT(IN) :: ncell_tot, nlev, nq
[342]263
[880]264   REAL(rstd) :: field_tmp(ncell_tot,nlev,nq)
265   TYPE(t_cellset), POINTER :: cellset
[922]266   INTEGER :: ind, n_beg, n, ij, sgn
[880]267   LOGICAL :: signed
[394]268
[880]269   CALL xios_recv_field(name,field_tmp)
270
271   IF(ALLOCATED(cells(1)%sgn)) THEN
272      signed=.TRUE.
273   ELSE
274      signed=.FALSE.
275      sgn=1
276   END IF
277
278   n_beg=0
279   DO ind=1,ndomain
280      cellset => cells(ind)
281      DO n=1, cellset%ncell
282         ij = cellset%ij(n)
283         IF(signed) sgn = cellset%sgn(n)
284         SELECT CASE(field(1)%ndim)
285         CASE(2)
286            field(ind)%rval2d(ij) = sgn*field_tmp(n_beg+n,1,1) 
287         CASE(3)
288            field(ind)%rval3d(ij,:) = sgn*field_tmp(n_beg+n,:,1)
289         CASE(4)
290            field(ind)%rval4d(ij,:,:) = sgn*field_tmp(n_beg+n,:,:)
291         END SELECT
292      END DO
[922]293      n_beg = n_beg + cellset%ncell
[880]294   END DO
295 END SUBROUTINE xios_read_field_hex
296
[505]297 SUBROUTINE xios_read_var(name,field)
298   USE prec
[726]299   USE transfert_mod
[505]300   CHARACTER(LEN=*),INTENT(IN) :: name
301   REAL(rstd), INTENT(OUT) :: field
[726]302   !$OMP MASTER
[505]303   CALL xios_recv_field(name,field)
[726]304   !$OMP END MASTER
305   CALL bcast_omp(field)
[505]306 END SUBROUTINE
[483]307 
[171]308 SUBROUTINE xios_write_field_finalize
[186]309!$OMP BARRIER
310!$OMP MASTER
[171]311   CALL xios_context_finalize
[186]312!$OMP END MASTER
313!$OMP BARRIER
[171]314 END SUBROUTINE xios_write_field_finalize
[266]315
316 SUBROUTINE xios_set_context
317  TYPE(xios_context) :: ctx_hdl
318
319!$OMP MASTER
320   CALL xios_get_handle("icosagcm",ctx_hdl)
321   CALL xios_set_current_context(ctx_hdl)
322!$OMP END MASTER
323
324  END SUBROUTINE xios_set_context
[482]325
326
[171]327#else
328 
[482]329
330INTERFACE xios_send_field
331  MODULE PROCEDURE xios_send_field_scalar, xios_send_field_1d
332END INTERFACE  xios_send_field
333
[483]334INTEGER,PARAMETER :: xios_timestep=1
[482]335
336CONTAINS 
337 
338 
[171]339  SUBROUTINE xios_init
[880]340    using_xios=.FALSE.   
[171]341  END SUBROUTINE xios_init
342 
[482]343  SUBROUTINE xios_send_field_scalar(name,field)
344    CHARACTER(LEN=*),INTENT(IN) :: name
345    REAL,INTENT(IN) :: field
346  END SUBROUTINE xios_send_field_scalar 
347
348  SUBROUTINE xios_send_field_1d(name,field)
349    CHARACTER(LEN=*),INTENT(IN) :: name
350    REAL,INTENT(IN) :: field(:)
351  END SUBROUTINE xios_send_field_1d 
352 
[171]353  SUBROUTINE xios_write_field(name,field)
354  USE field_mod
355   CHARACTER(LEN=*),INTENT(IN) :: name
356   TYPE(t_field), POINTER :: field(:)
357  END SUBROUTINE xios_write_field
[482]358
359  SUBROUTINE xios_read_field(name,field)
360  USE field_mod
361   CHARACTER(LEN=*),INTENT(IN) :: name
362   TYPE(t_field), POINTER :: field(:)
363  END SUBROUTINE xios_read_field
[505]364
365 SUBROUTINE xios_read_var(name,field)
366   USE prec
367   CHARACTER(LEN=*),INTENT(IN) :: name
368   REAL(rstd), INTENT(OUT) :: field
369 END SUBROUTINE
[171]370 
371  SUBROUTINE xios_update_calendar(step)
372   INTEGER, INTENT(IN):: step 
373  END SUBROUTINE xios_update_calendar
374
375  SUBROUTINE xios_write_field_finalize
376  END SUBROUTINE xios_write_field_finalize
377 
378  SUBROUTINE xios_init_write_field
379  END SUBROUTINE xios_init_write_field 
[266]380 
381  SUBROUTINE xios_set_context
382  END SUBROUTINE xios_set_context
383 
[483]384  SUBROUTINE xios_set_fieldgroup_attr(name,enabled,freq_op)
[482]385    CHARACTER(LEN=*) :: name
386    LOGICAL,OPTIONAL          :: enabled
[483]387    INTEGER,OPTIONAL          :: freq_op
[482]388  END SUBROUTINE xios_set_fieldgroup_attr
[266]389
[482]390  SUBROUTINE xios_set_filegroup_attr(name,enabled)
391    CHARACTER(LEN=*) :: name
392    LOGICAL,OPTIONAL          :: enabled
393  END SUBROUTINE xios_set_filegroup_attr
394
[551]395  SUBROUTINE xios_set_file_attr(id,name,mode,enabled, output_freq)
[483]396    CHARACTER(LEN=*) :: id
[551]397    CHARACTER(LEN=*),OPTIONAL :: name, mode
[483]398    LOGICAL,OPTIONAL          :: enabled
399    INTEGER,OPTIONAL          :: output_freq
400  END SUBROUTINE xios_set_file_attr
401
[482]402  SUBROUTINE xios_get_axis_attr(name,n_glo,value)
403    CHARACTER(LEN=*) :: name
404    INTEGER,OPTIONAL          :: n_glo
405    REAL,OPTIONAL             :: value(:)
406  END SUBROUTINE xios_get_axis_attr
407
[483]408  SUBROUTINE xios_set_axis_attr(id,n_glo,value)
409    CHARACTER(LEN=*) :: id
410    INTEGER,OPTIONAL          :: n_glo
411    REAL,OPTIONAL             :: value(:)
412  END SUBROUTINE xios_set_axis_attr
413
[171]414#endif 
[482]415
[171]416END MODULE xios_mod
Note: See TracBrowser for help on using the repository browser.