FV3 Bundle
type_nam.F90
Go to the documentation of this file.
1 !----------------------------------------------------------------------
2 ! Module: type_nam
3 ! Purpose: namelist derived type
4 ! Author: Benjamin Menetrier
5 ! Licensing: this code is distributed under the CeCILL-C license
6 ! Copyright © 2015-... UCAR, CERFACS, METEO-FRANCE and IRIT
7 !----------------------------------------------------------------------
8 module type_nam
9 
10 use iso_c_binding
11 use netcdf, only: nf90_put_att,nf90_global
12 !$ use omp_lib, only: omp_get_num_procs
13 use tools_const, only: req,deg2rad,rad2deg
14 use tools_kinds,only: kind_real
15 use tools_missing, only: msi,msr
16 use tools_nc, only: put_att
17 use type_mpl, only: mpl_type
18 
19 implicit none
20 
21 integer,parameter :: nvmax = 20 ! Maximum number of variables
22 integer,parameter :: ntsmax = 20 ! Maximum number of time slots
23 integer,parameter :: nlmax = 200 ! Maximum number of levels
24 integer,parameter :: nc3max = 1000 ! Maximum number of classes
25 integer,parameter :: nscalesmax = 5 ! Maximum number of variables
26 integer,parameter :: ndirmax = 300 ! Maximum number of diracs
27 integer,parameter :: nldwvmax = 100 ! Maximum number of local diagnostic profiles
28 
30  ! general_param
31  character(len=1024) :: datadir ! Data directory
32  character(len=1024) :: prefix ! Files prefix
33  character(len=1024) :: model ! Model name ('aro', 'arp', 'fv3', 'gem', 'geos', 'gfs', 'ifs', 'mpas', 'nemo' or 'wrf')
34  logical :: colorlog ! Add colors to the log (for display on terminal)
35  logical :: default_seed ! Default seed for random numbers
36 
37  ! driver_param
38  character(len=1024) :: method ! Localization/hybridization to compute ('cor', 'loc_norm', 'loc', 'hyb-avg', 'hyb-rnd' or 'dual-ens')
39  character(len=1024) :: strategy ! Localization strategy ('diag_all', 'common', 'common_univariate', 'common_weighted', 'specific_univariate' or 'specific_multivariate')
40  logical :: new_vbal ! Compute new vertical balance operator
41  logical :: load_vbal ! Load existing vertical balance operator
42  logical :: new_hdiag ! Compute new HDIAG diagnostics
43  logical :: new_lct ! Compute new LCT
44  logical :: load_cmat ! Load existing C matrix
45  logical :: new_nicas ! Compute new NICAS parameters
46  logical :: load_nicas ! Load existing NICAS parameters
47  logical :: new_obsop ! Compute new observation operator
48  logical :: load_obsop ! Load existing observation operator
49  logical :: check_vbal ! Test vertical balance inverse and adjoint
50  logical :: check_adjoints ! Test NICAS adjoints
51  logical :: check_pos_def ! Test NICAS positive definiteness
52  logical :: check_sqrt ! Test NICAS full/square-root equivalence
53  logical :: check_dirac ! Test NICAS application on diracs
54  logical :: check_randomization ! Test NICAS randomization
55  logical :: check_consistency ! Test HDIAG-NICAS consistency
56  logical :: check_optimality ! Test HDIAG optimality
57  logical :: check_obsop ! Test observation operator
58 
59  ! model_param
60  integer :: nl ! Number of levels
61  integer :: levs(nlmax) ! Levels
62  logical :: logpres ! Use pressure logarithm as vertical coordinate (model level if .false.)
63  integer :: nv ! Number of variables
64  character(len=1024),dimension(nvmax) :: varname ! Variables names
65  character(len=1024),dimension(nvmax) :: addvar2d ! Additionnal 2d variables names
66  integer :: nts ! Number of time slots
67  integer,dimension(ntsmax) :: timeslot ! Timeslots
68 
69  ! ens1_param
70  integer :: ens1_ne ! Ensemble 1 size
71  integer :: ens1_ne_offset ! Ensemble 1 index offset
72  integer :: ens1_nsub ! Ensemble 1 sub-ensembles number
73 
74  ! ens2_param
75  integer :: ens2_ne ! Ensemble 2 size
76  integer :: ens2_ne_offset ! Ensemble 2 index offset
77  integer :: ens2_nsub ! Ensemble 2 sub-ensembles number
78 
79  ! sampling_param
80  logical :: sam_write ! Write sampling
81  logical :: sam_read ! Read sampling
82  character(len=1024) :: mask_type ! Mask restriction type
83  real(kind_real) :: mask_th ! Mask threshold
84  logical :: mask_check ! Check that sampling couples and interpolations do not cross mask boundaries
85  character(len=1024) :: draw_type ! Sampling draw type ('random_uniform','random_coast' or 'icosahedron')
86  integer :: nc1 ! Number of sampling points
87  integer :: nc2 ! Number of diagnostic points
88  integer :: ntry ! Number of tries to get the most separated point for the zero-separation sampling
89  integer :: nrep ! Number of replacement to improve homogeneity of the zero-separation sampling
90  integer :: nc3 ! Number of classes
91  real(kind_real) :: dc ! Class size (for sam_type='hor'), should be larger than the typical grid cell size
92  integer :: nl0r ! Reduced number of levels for diagnostics
93 
94  ! diag_param
95  integer :: ne ! Ensemble size
96  logical :: gau_approx ! Gaussian approximation for asymptotic quantities
97  logical :: vbal_block(nvmax*(nvmax-1)/2) ! Activation of vertical balance (ordered line by line in the lower triangular formulation)
98  real(kind_real) :: vbal_rad ! Vertical balance diagnostic radius
99  logical :: var_diag ! Compute variances
100  logical :: var_filter ! Filter variances
101  integer :: var_niter ! Number of iteration for the variances filtering (for var_filter = .true.)
102  real(kind_real) :: var_rhflt ! Variances initial filtering support radius (for var_filter = .true.)
103  logical :: var_full ! Compute variances on full grid
104  logical :: local_diag ! Activate local diagnostics
105  real(kind_real) :: local_rad ! Local diagnostics calculation radius (for local_rad = .true.)
106  logical :: displ_diag ! Activate displacement diagnostics
107  real(kind_real) :: displ_rad ! Displacement diagnostics calculation radius
108  integer :: displ_niter ! Number of iteration for the displacement filtering (for displ_diag = .true.)
109  real(kind_real) :: displ_rhflt ! Displacement initial filtering support radius (for displ_diag = .true.)
110  real(kind_real) :: displ_tol ! Displacement tolerance for mesh check (for displ_diag = .true.)
111 
112  ! fit_param
113  character(len=1024) :: minim_algo ! Minimization algorithm ('none', 'fast' or 'hooke')
114  logical :: double_fit(0:nvmax) ! Double fit to introduce negative lobes on the vertical
115  logical :: lhomh ! Vertically homogenous horizontal support radius
116  logical :: lhomv ! Vertically homogenous vertical support radius
117  real(kind_real) :: rvflt ! Vertical smoother support radius
118  integer :: lct_nscales ! Number of LCT scales
119  logical :: lct_diag(nscalesmax) ! Diagnostic of diagonal LCT components only
120 
121  ! nicas_param
122  logical :: lsqrt ! Square-root formulation
123  real(kind_real) :: resol ! Resolution
124  logical :: fast_sampling ! Fast sampling flag
125  character(len=1024) :: nicas_interp ! NICAS interpolation type
126  logical :: network ! Network-base convolution calculation (distance-based if false)
127  integer :: mpicom ! Number of communication steps
128  integer :: advmode ! Advection mode (1: direct, -1: direct and inverse)
129  logical :: forced_radii ! Force specific support radii
130  real(kind_real) :: rh ! Forced horizontal support radius
131  real(kind_real) :: rv ! Forced vertical support radius
132  integer :: ndir ! Number of Diracs
133  real(kind_real) :: londir(ndirmax) ! Diracs longitudes (in degrees)
134  real(kind_real) :: latdir(ndirmax) ! Diracs latitudes (in degrees)
135  integer :: levdir(ndirmax) ! Diracs level
136  integer :: ivdir(ndirmax) ! Diracs variable
137  integer :: itsdir(ndirmax) ! Diracs timeslot
138 
139  ! obsop_param
140  integer :: nobs ! Number of observations
141  character(len=1024) :: obsdis ! Observation distribution parameter
142  character(len=1024) :: obsop_interp ! Observation operator interpolation type
143 
144  ! output_param
145  integer :: nldwh ! Number of local diagnostics fields to write (for local_diag = .true.)
146  integer :: il_ldwh(nlmax*nc3max) ! Levels of local diagnostics fields to write (for local_diag = .true.)
147  integer :: ic_ldwh(nlmax*nc3max) ! Classes of local diagnostics fields to write (for local_diag = .true.)
148  integer :: nldwv ! Number of local diagnostics profiles to write (for local_diag = .true.)
149  real(kind_real) :: lon_ldwv(nldwvmax) ! Longitudes (in degrees) local diagnostics profiles to write (for local_diag = .true.)
150  real(kind_real) :: lat_ldwv(nldwvmax) ! Latitudes (in degrees) local diagnostics profiles to write (for local_diag = .true.)
151  real(kind_real) :: diag_rhflt ! Diagnostics filtering radius
152  character(len=1024) :: diag_interp ! Diagnostics interpolation type
153  logical :: field_io ! Field I/O
154  logical :: split_io ! Split I/O (each task read and write its own file)
155  logical :: grid_output ! Write regridded fields
156  real(kind_real) :: grid_resol ! Regridded fields resolution
157  character(len=1024) :: grid_interp ! Regridding interpolation type
158 contains
159  procedure :: init => nam_init
160  procedure :: read => nam_read
161  procedure :: bcast => nam_bcast
162  procedure :: setup_internal => nam_setup_internal
163  procedure :: check => nam_check
164  procedure :: ncwrite => nam_ncwrite
165 end type nam_type
166 
167 private
169 public :: nam_type
170 
171 contains
172 
173 !----------------------------------------------------------------------
174 ! Subroutine: nam_init
175 ! Purpose: intialize namelist parameters
176 !----------------------------------------------------------------------
177 subroutine nam_init(nam)
179 implicit none
180 
181 ! Passed variable
182 class(nam_type),intent(out) :: nam ! Namelist
183 
184 ! Local variable
185 integer :: iv
186 
187 ! general_param default
188 nam%datadir = ''
189 nam%prefix = ''
190 nam%model = ''
191 nam%colorlog = .false.
192 nam%default_seed = .false.
193 
194 ! driver_param default
195 nam%method = ''
196 nam%strategy = ''
197 nam%new_vbal = .false.
198 nam%load_vbal = .false.
199 nam%new_hdiag = .false.
200 nam%new_lct = .false.
201 nam%load_cmat = .false.
202 nam%new_nicas = .false.
203 nam%load_nicas = .false.
204 nam%new_obsop = .false.
205 nam%load_obsop = .false.
206 nam%check_vbal = .false.
207 nam%check_adjoints = .false.
208 nam%check_pos_def = .false.
209 nam%check_sqrt = .false.
210 nam%check_dirac = .false.
211 nam%check_randomization = .false.
212 nam%check_consistency = .false.
213 nam%check_optimality = .false.
214 nam%check_obsop = .false.
215 
216 ! model_param default
217 call msi(nam%nl)
218 call msi(nam%levs)
219 nam%logpres = .false.
220 call msi(nam%nv)
221 do iv=1,nvmax
222  nam%varname(iv) = ''
223  nam%addvar2d(iv) = ''
224 end do
225 call msi(nam%nts)
226 call msi(nam%timeslot)
227 
228 ! ens1_param default
229 call msi(nam%ens1_ne)
230 call msi(nam%ens1_ne_offset)
231 call msi(nam%ens1_nsub)
232 
233 ! ens2_param default
234 call msi(nam%ens2_ne)
235 call msi(nam%ens2_ne_offset)
236 call msi(nam%ens2_nsub)
237 
238 ! sampling_param default
239 nam%sam_write = .false.
240 nam%sam_read = .false.
241 nam%mask_type = ''
242 call msr(nam%mask_th)
243 nam%mask_check = .false.
244 nam%draw_type = ''
245 call msi(nam%nc1)
246 call msi(nam%nc2)
247 call msi(nam%ntry)
248 call msi(nam%nrep)
249 call msi(nam%nc3)
250 call msr(nam%dc)
251 call msi(nam%nl0r)
252 
253 ! diag_param default
254 call msi(nam%ne)
255 nam%gau_approx = .false.
256 do iv=1,nvmax*(nvmax-1)/2
257  nam%vbal_block(iv) = .false.
258 end do
259 call msr(nam%vbal_rad)
260 nam%var_diag = .false.
261 nam%var_filter = .false.
262 nam%var_full = .false.
263 call msi(nam%var_niter)
264 call msr(nam%var_rhflt)
265 nam%local_diag = .false.
266 call msr(nam%local_rad)
267 nam%displ_diag = .false.
268 call msr(nam%displ_rad)
269 call msi(nam%displ_niter)
270 call msr(nam%displ_rhflt)
271 call msr(nam%displ_tol)
272 
273 ! fit_param default
274 nam%minim_algo = ''
275 do iv=0,nvmax
276  nam%double_fit(iv) = .false.
277 end do
278 nam%lhomh = .false.
279 nam%lhomv = .false.
280 call msr(nam%rvflt)
281 call msi(nam%lct_nscales)
282 nam%lct_diag = .false.
283 
284 ! nicas_param default
285 nam%lsqrt = .false.
286 call msr(nam%resol)
287 nam%fast_sampling = .false.
288 nam%nicas_interp = ''
289 nam%network = .false.
290 call msi(nam%mpicom)
291 call msi(nam%advmode)
292 nam%forced_radii = .false.
293 call msr(nam%rh)
294 call msr(nam%rv)
295 call msi(nam%ndir)
296 call msr(nam%londir)
297 call msr(nam%latdir)
298 call msi(nam%levdir)
299 call msi(nam%ivdir)
300 call msi(nam%itsdir)
301 
302 ! obsop_param default
303 call msi(nam%nobs)
304 nam%obsdis = ''
305 nam%obsop_interp = ''
306 
307 ! output_param default
308 call msi(nam%nldwh)
309 call msi(nam%il_ldwh)
310 call msi(nam%ic_ldwh)
311 call msi(nam%nldwv)
312 call msr(nam%lon_ldwv)
313 call msr(nam%lat_ldwv)
314 call msr(nam%diag_rhflt)
315 nam%diag_interp = ''
316 nam%field_io = .true.
317 nam%split_io = .false.
318 nam%grid_output = .false.
319 call msr(nam%grid_resol)
320 nam%grid_interp = ''
321 
322 end subroutine nam_init
323 
324 !----------------------------------------------------------------------
325 ! Subroutine: nam_read
326 ! Purpose: read namelist parameters
327 !----------------------------------------------------------------------
328 subroutine nam_read(nam,mpl,namelname)
330 implicit none
331 
332 ! Passed variable
333 class(nam_type),intent(inout) :: nam ! Namelist
334 type(mpl_type),intent(in) :: mpl ! MPI data
335 character(len=*),intent(in) :: namelname ! Namelist name
336 
337 ! Local variables
338 integer :: iv
339 
340 ! Namelist variables
341 integer :: lunit
342 integer :: nl,levs(nlmax),nv,nts,timeslot(ntsmax),ens1_ne,ens1_ne_offset,ens1_nsub,ens2_ne,ens2_ne_offset,ens2_nsub
343 integer :: nc1,nc2,ntry,nrep,nc3,nl0r,ne,var_niter,displ_niter,lct_nscales,mpicom,advmode,ndir,levdir(ndirmax),ivdir(ndirmax)
344 integer :: itsdir(ndirmax),nobs,nldwh,il_ldwh(nlmax*nc3max),ic_ldwh(nlmax*nc3max),nldwv
345 logical :: colorlog,default_seed
346 logical :: new_vbal,load_vbal,new_hdiag,new_lct,load_cmat,new_nicas,load_nicas,new_obsop,load_obsop
347 logical :: check_vbal,check_adjoints,check_pos_def,check_sqrt,check_dirac,check_randomization,check_consistency,check_optimality
348 logical :: check_obsop,logpres,sam_write,sam_read,mask_check
349 logical :: vbal_block(nvmax*(nvmax-1)/2),var_diag,var_filter,var_full,gau_approx,local_diag,displ_diag,double_fit(0:nvmax)
350 logical :: lhomh,lhomv,lct_diag(nscalesmax),lsqrt,fast_sampling,network,forced_radii,field_io,split_io,grid_output
351 real(kind_real) :: mask_th,dc,vbal_rad,var_rhflt,local_rad,displ_rad,displ_rhflt,displ_tol,rvflt,lon_ldwv(nldwvmax)
352 real(kind_real) :: lat_ldwv(nldwvmax),diag_rhflt,resol,rh,rv,londir(ndirmax),latdir(ndirmax),grid_resol
353 character(len=1024) :: datadir,prefix,model,strategy,method,mask_type,draw_type,minim_algo,nicas_interp
354 character(len=1024) :: obsdis,obsop_interp,diag_interp,grid_interp
355 character(len=1024),dimension(nvmax) :: varname,addvar2d
356 
357 ! Namelist blocks
358 namelist/general_param/datadir,prefix,model,colorlog,default_seed
359 namelist/driver_param/method,strategy,new_vbal,load_vbal,new_hdiag,new_lct,load_cmat,new_nicas,load_nicas,new_obsop,load_obsop, &
360  & check_vbal,check_adjoints,check_pos_def,check_sqrt,check_dirac,check_randomization,check_consistency, &
361  & check_optimality,check_obsop
362 namelist/model_param/nl,levs,logpres,nv,varname,addvar2d,nts,timeslot
363 namelist/ens1_param/ens1_ne,ens1_ne_offset,ens1_nsub
364 namelist/ens2_param/ens2_ne,ens2_ne_offset,ens2_nsub
365 namelist/sampling_param/sam_write,sam_read,mask_type,mask_th,mask_check,draw_type,nc1,nc2,ntry,nrep,nc3,dc,nl0r
366 namelist/diag_param/ne,gau_approx,vbal_block,vbal_rad,var_diag,var_filter,var_full,var_niter,var_rhflt,local_diag,local_rad, &
367  & displ_diag,displ_rad,displ_niter,displ_rhflt,displ_tol
368 namelist/fit_param/minim_algo,double_fit,lhomh,lhomv,rvflt,lct_nscales,lct_diag
369 namelist/nicas_param/lsqrt,resol,fast_sampling,nicas_interp,network,mpicom,advmode,forced_radii,rh,rv,ndir,londir,latdir,levdir, &
370  & ivdir,itsdir
371 namelist/obsop_param/nobs,obsdis,obsop_interp
372 namelist/output_param/nldwh,il_ldwh,ic_ldwh,nldwv,lon_ldwv,lat_ldwv,diag_rhflt,diag_interp,field_io,split_io, &
373  & grid_output,grid_resol,grid_interp
374 
375 if (mpl%main) then
376  ! general_param default
377  datadir = ''
378  prefix = ''
379  model = ''
380  colorlog = .false.
381  default_seed = .false.
382 
383  ! driver_param default
384  method = ''
385  strategy = ''
386  new_vbal = .false.
387  load_vbal = .false.
388  new_hdiag = .false.
389  new_lct = .false.
390  load_cmat = .false.
391  new_nicas = .false.
392  load_nicas = .false.
393  new_obsop = .false.
394  load_obsop = .false.
395  check_vbal = .false.
396  check_adjoints = .false.
397  check_pos_def = .false.
398  check_sqrt = .false.
399  check_dirac = .false.
400  check_randomization = .false.
401  check_consistency = .false.
402  check_optimality = .false.
403  check_obsop = .false.
404 
405  ! model_param default
406  call msi(nl)
407  call msi(levs)
408  logpres = .false.
409  call msi(nv)
410  do iv=1,nvmax
411  varname(iv) = ''
412  addvar2d(iv) = ''
413  end do
414  call msi(nts)
415  call msi(timeslot)
416 
417  ! ens1_param default
418  call msi(ens1_ne)
419  call msi(ens1_ne_offset)
420  call msi(ens1_nsub)
421 
422  ! ens2_param default
423  call msi(ens2_ne)
424  call msi(ens2_ne_offset)
425  call msi(ens2_nsub)
426 
427  ! sampling_param default
428  sam_write = .false.
429  sam_read = .false.
430  mask_type = ''
431  call msr(mask_th)
432  mask_check = .false.
433  draw_type = ''
434  call msi(nc1)
435  call msi(nc2)
436  call msi(ntry)
437  call msi(nrep)
438  call msi(nc3)
439  call msr(dc)
440  call msi(nl0r)
441 
442  ! diag_param default
443  call msi(ne)
444  gau_approx = .false.
445  do iv=1,nvmax*(nvmax-1)/2
446  vbal_block(iv) = .false.
447  end do
448  call msr(vbal_rad)
449  var_diag = .false.
450  var_filter = .false.
451  var_full = .false.
452  call msi(var_niter)
453  call msr(var_rhflt)
454  local_diag = .false.
455  call msr(local_rad)
456  displ_diag = .false.
457  call msr(displ_rad)
458  call msi(displ_niter)
459  call msr(displ_rhflt)
460  call msr(displ_tol)
461 
462  ! fit_param default
463  minim_algo = ''
464  do iv=0,nvmax
465  double_fit(iv) = .false.
466  end do
467  lhomh = .false.
468  lhomv = .false.
469  call msr(rvflt)
470  call msi(lct_nscales)
471  lct_diag = .false.
472 
473  ! nicas_param default
474  lsqrt = .false.
475  call msr(resol)
476  nicas_interp = ''
477  network = .false.
478  call msi(mpicom)
479  call msi(advmode)
480  forced_radii = .false.
481  call msr(rh)
482  call msr(rv)
483  call msi(ndir)
484  call msr(londir)
485  call msr(latdir)
486  call msi(levdir)
487  call msi(ivdir)
488  call msi(itsdir)
489 
490  ! obsop_param default
491  call msi(nobs)
492  obsdis = ''
493  obsop_interp = ''
494 
495  ! output_param default
496  call msi(nldwh)
497  call msi(il_ldwh)
498  call msi(ic_ldwh)
499  call msi(nldwv)
500  call msr(lon_ldwv)
501  call msr(lat_ldwv)
502  call msr(diag_rhflt)
503  diag_interp = ''
504  field_io = .true.
505  split_io = .false.
506  grid_output = .false.
507  call msr(grid_resol)
508  grid_interp = ''
509 
510  ! Open namelist
511  call mpl%newunit(lunit)
512  open(unit=lunit,file=trim(namelname),status='old',action='read')
513 
514  ! general_param
515  read(lunit,nml=general_param)
516  nam%datadir = datadir
517  nam%prefix = prefix
518  nam%model = model
519  nam%colorlog = colorlog
520  nam%default_seed = default_seed
521 
522  ! driver_param
523  read(lunit,nml=driver_param)
524  nam%method = method
525  nam%strategy = strategy
526  nam%new_vbal = new_vbal
527  nam%load_vbal = load_vbal
528  nam%new_hdiag = new_hdiag
529  nam%new_lct = new_lct
530  nam%load_cmat = load_cmat
531  nam%new_nicas = new_nicas
532  nam%load_nicas = load_nicas
533  nam%new_obsop = new_obsop
534  nam%load_obsop = load_obsop
535  nam%check_vbal = check_vbal
536  nam%check_adjoints = check_adjoints
537  nam%check_pos_def = check_pos_def
538  nam%check_sqrt = check_sqrt
539  nam%check_dirac = check_dirac
540  nam%check_randomization = check_randomization
541  nam%check_consistency = check_consistency
542  nam%check_optimality = check_optimality
543  nam%check_obsop = check_obsop
544 
545  ! model_param
546  read(lunit,nml=model_param)
547  if (nl>nlmax) call mpl%abort('nl is too large')
548  if (nv>nvmax) call mpl%abort('nv is too large')
549  if (nts>ntsmax) call mpl%abort('nts is too large')
550  nam%nl = nl
551  if (nl>0) nam%levs(1:nl) = levs(1:nl)
552  nam%logpres = logpres
553  nam%nv = nv
554  if (nv>0) nam%varname(1:nv) = varname(1:nv)
555  if (nv>0) nam%addvar2d(1:nv) = addvar2d(1:nv)
556  nam%nts = nts
557  if (nts>0) nam%timeslot(1:nts) = timeslot(1:nts)
558 
559  ! ens1_param
560  read(lunit,nml=ens1_param)
561  nam%ens1_ne = ens1_ne
562  nam%ens1_ne_offset = ens1_ne_offset
563  nam%ens1_nsub = ens1_nsub
564 
565  ! ens2_param
566  read(lunit,nml=ens2_param)
567  nam%ens2_ne = ens2_ne
568  nam%ens2_ne_offset = ens2_ne_offset
569  nam%ens2_nsub = ens2_nsub
570 
571  ! sampling_param
572  read(lunit,nml=sampling_param)
573  if (nc3>nc3max) call mpl%abort('nc3 is too large')
574  nam%sam_write = sam_write
575  nam%sam_read = sam_read
576  nam%mask_type = mask_type
577  nam%mask_th = mask_th
578  nam%mask_check = mask_check
579  nam%draw_type = draw_type
580  nam%nc1 = nc1
581  nam%nc2 = nc2
582  nam%ntry = ntry
583  nam%nrep = nrep
584  nam%nc3 = nc3
585  nam%dc = dc
586  nam%nl0r = nl0r
587 
588  ! diag_param
589  read(lunit,nml=diag_param)
590  nam%ne = ne
591  nam%gau_approx = gau_approx
592  if (nv>1) nam%vbal_block(1:nam%nv*(nam%nv-1)/2) = vbal_block(1:nam%nv*(nam%nv-1)/2)
593  nam%vbal_rad = vbal_rad
594  nam%var_diag = var_diag
595  nam%var_filter = var_filter
596  nam%var_full = var_full
597  nam%var_niter = var_niter
598  nam%var_rhflt = var_rhflt
599  nam%local_diag = local_diag
600  nam%local_rad = local_rad
601  nam%displ_diag = displ_diag
602  nam%displ_rad = displ_rad
603  nam%displ_niter = displ_niter
604  nam%displ_rhflt = displ_rhflt
605  nam%displ_tol = displ_tol
606 
607  ! fit_param
608  read(lunit,nml=fit_param)
609  if (lct_nscales>nscalesmax) call mpl%abort('lct_nscales is too large')
610  nam%minim_algo = minim_algo
611  if (nv>0) nam%double_fit(1:nv) = double_fit(1:nv)
612  nam%lhomh = lhomh
613  nam%lhomv = lhomv
614  nam%rvflt = rvflt
615  nam%lct_nscales = lct_nscales
616  if (lct_nscales>0) nam%lct_diag(1:lct_nscales) = lct_diag(1:lct_nscales)
617 
618  ! nicas_param
619  read(lunit,nml=nicas_param)
620  if (ndir>ndirmax) call mpl%abort('ndir is too large')
621  nam%lsqrt = lsqrt
622  nam%resol = resol
623  nam%fast_sampling = fast_sampling
624  nam%nicas_interp = nicas_interp
625  nam%network = network
626  nam%mpicom = mpicom
627  nam%advmode = advmode
628  nam%forced_radii = forced_radii
629  nam%rh = rh
630  nam%rv = rv
631  nam%ndir = ndir
632  if (ndir>0) nam%londir(1:ndir) = londir(1:ndir)
633  if (ndir>0) nam%latdir(1:ndir) = latdir(1:ndir)
634  if (ndir>0) nam%levdir(1:ndir) = levdir(1:ndir)
635  if (ndir>0) nam%ivdir(1:ndir) = ivdir(1:ndir)
636  if (ndir>0) nam%itsdir(1:ndir) = itsdir(1:ndir)
637 
638  ! obsop_param
639  read(lunit,nml=obsop_param)
640  nam%nobs = nobs
641  nam%obsdis = obsdis
642  nam%obsop_interp = obsop_interp
643 
644  ! output_param
645  read(lunit,nml=output_param)
646  if (nldwh>nlmax*nc3max) call mpl%abort('nldwh is too large')
647  if (nldwv>nldwvmax) call mpl%abort('nldwv is too large')
648  nam%nldwh = nldwh
649  if (nldwh>0) nam%il_ldwh(1:nldwh) = il_ldwh(1:nldwh)
650  if (nldwh>0) nam%ic_ldwh(1:nldwh) = ic_ldwh(1:nldwh)
651  nam%nldwv = nldwv
652  if (nldwv>0) nam%lon_ldwv(1:nldwv) = lon_ldwv(1:nldwv)
653  if (nldwv>0) nam%lat_ldwv(1:nldwv) = lat_ldwv(1:nldwv)
654  nam%diag_rhflt = diag_rhflt
655  nam%diag_interp = diag_interp
656  nam%field_io = field_io
657  nam%split_io = split_io
658  nam%grid_output = grid_output
659  nam%grid_resol = grid_resol
660  nam%grid_interp = grid_interp
661 
662  ! Close namelist
663  close(unit=lunit)
664 end if
665 
666 end subroutine nam_read
667 
668 !----------------------------------------------------------------------
669 ! Subroutine: nam_bcast
670 ! Purpose: broadcast namelist parameters
671 !----------------------------------------------------------------------
672 subroutine nam_bcast(nam,mpl)
674 implicit none
675 
676 ! Passed variable
677 class(nam_type),intent(inout) :: nam ! Namelist
678 type(mpl_type),intent(in) :: mpl ! MPI data
679 
680 ! general_param
681 call mpl%f_comm%broadcast(nam%datadir,mpl%ioproc-1)
682 call mpl%f_comm%broadcast(nam%prefix,mpl%ioproc-1)
683 call mpl%f_comm%broadcast(nam%model,mpl%ioproc-1)
684 call mpl%f_comm%broadcast(nam%colorlog,mpl%ioproc-1)
685 call mpl%f_comm%broadcast(nam%default_seed,mpl%ioproc-1)
686 
687 ! driver_param
688 call mpl%f_comm%broadcast(nam%method,mpl%ioproc-1)
689 call mpl%f_comm%broadcast(nam%strategy,mpl%ioproc-1)
690 call mpl%f_comm%broadcast(nam%new_vbal,mpl%ioproc-1)
691 call mpl%f_comm%broadcast(nam%load_vbal,mpl%ioproc-1)
692 call mpl%f_comm%broadcast(nam%new_hdiag,mpl%ioproc-1)
693 call mpl%f_comm%broadcast(nam%new_lct,mpl%ioproc-1)
694 call mpl%f_comm%broadcast(nam%load_cmat,mpl%ioproc-1)
695 call mpl%f_comm%broadcast(nam%new_nicas,mpl%ioproc-1)
696 call mpl%f_comm%broadcast(nam%load_nicas,mpl%ioproc-1)
697 call mpl%f_comm%broadcast(nam%new_obsop,mpl%ioproc-1)
698 call mpl%f_comm%broadcast(nam%load_obsop,mpl%ioproc-1)
699 call mpl%f_comm%broadcast(nam%check_vbal,mpl%ioproc-1)
700 call mpl%f_comm%broadcast(nam%check_adjoints,mpl%ioproc-1)
701 call mpl%f_comm%broadcast(nam%check_pos_def,mpl%ioproc-1)
702 call mpl%f_comm%broadcast(nam%check_sqrt,mpl%ioproc-1)
703 call mpl%f_comm%broadcast(nam%check_dirac,mpl%ioproc-1)
704 call mpl%f_comm%broadcast(nam%check_randomization,mpl%ioproc-1)
705 call mpl%f_comm%broadcast(nam%check_consistency,mpl%ioproc-1)
706 call mpl%f_comm%broadcast(nam%check_optimality,mpl%ioproc-1)
707 call mpl%f_comm%broadcast(nam%check_obsop,mpl%ioproc-1)
708 
709 ! model_param
710 call mpl%f_comm%broadcast(nam%nl,mpl%ioproc-1)
711 call mpl%f_comm%broadcast(nam%levs,mpl%ioproc-1)
712 call mpl%f_comm%broadcast(nam%logpres,mpl%ioproc-1)
713 call mpl%f_comm%broadcast(nam%nv,mpl%ioproc-1)
714 call mpl%bcast(nam%varname,mpl%ioproc-1)
715 call mpl%bcast(nam%addvar2d,mpl%ioproc-1)
716 call mpl%f_comm%broadcast(nam%nts,mpl%ioproc-1)
717 call mpl%f_comm%broadcast(nam%timeslot,mpl%ioproc-1)
718 
719 ! ens1_param
720 call mpl%f_comm%broadcast(nam%ens1_ne,mpl%ioproc-1)
721 call mpl%f_comm%broadcast(nam%ens1_ne_offset,mpl%ioproc-1)
722 call mpl%f_comm%broadcast(nam%ens1_nsub,mpl%ioproc-1)
723 
724 ! ens2_param
725 call mpl%f_comm%broadcast(nam%ens2_ne,mpl%ioproc-1)
726 call mpl%f_comm%broadcast(nam%ens2_ne_offset,mpl%ioproc-1)
727 call mpl%f_comm%broadcast(nam%ens2_nsub,mpl%ioproc-1)
728 
729 ! sampling_param
730 call mpl%f_comm%broadcast(nam%sam_write,mpl%ioproc-1)
731 call mpl%f_comm%broadcast(nam%sam_read,mpl%ioproc-1)
732 call mpl%f_comm%broadcast(nam%mask_type,mpl%ioproc-1)
733 call mpl%f_comm%broadcast(nam%mask_th,mpl%ioproc-1)
734 call mpl%f_comm%broadcast(nam%mask_check,mpl%ioproc-1)
735 call mpl%f_comm%broadcast(nam%draw_type,mpl%ioproc-1)
736 call mpl%f_comm%broadcast(nam%nc1,mpl%ioproc-1)
737 call mpl%f_comm%broadcast(nam%nc2,mpl%ioproc-1)
738 call mpl%f_comm%broadcast(nam%ntry,mpl%ioproc-1)
739 call mpl%f_comm%broadcast(nam%nrep,mpl%ioproc-1)
740 call mpl%f_comm%broadcast(nam%nc3,mpl%ioproc-1)
741 call mpl%f_comm%broadcast(nam%dc,mpl%ioproc-1)
742 call mpl%f_comm%broadcast(nam%nl0r,mpl%ioproc-1)
743 
744 ! diag_param
745 call mpl%f_comm%broadcast(nam%ne,mpl%ioproc-1)
746 call mpl%f_comm%broadcast(nam%gau_approx,mpl%ioproc-1)
747 call mpl%f_comm%broadcast(nam%vbal_block,mpl%ioproc-1)
748 call mpl%f_comm%broadcast(nam%vbal_rad,mpl%ioproc-1)
749 call mpl%f_comm%broadcast(nam%var_diag,mpl%ioproc-1)
750 call mpl%f_comm%broadcast(nam%var_filter,mpl%ioproc-1)
751 call mpl%f_comm%broadcast(nam%var_full,mpl%ioproc-1)
752 call mpl%f_comm%broadcast(nam%var_niter,mpl%ioproc-1)
753 call mpl%f_comm%broadcast(nam%var_rhflt,mpl%ioproc-1)
754 call mpl%f_comm%broadcast(nam%local_diag,mpl%ioproc-1)
755 call mpl%f_comm%broadcast(nam%local_rad,mpl%ioproc-1)
756 call mpl%f_comm%broadcast(nam%displ_diag,mpl%ioproc-1)
757 call mpl%f_comm%broadcast(nam%displ_rad,mpl%ioproc-1)
758 call mpl%f_comm%broadcast(nam%displ_niter,mpl%ioproc-1)
759 call mpl%f_comm%broadcast(nam%displ_rhflt,mpl%ioproc-1)
760 call mpl%f_comm%broadcast(nam%displ_tol,mpl%ioproc-1)
761 
762 ! fit_param
763 call mpl%f_comm%broadcast(nam%minim_algo,mpl%ioproc-1)
764 call mpl%f_comm%broadcast(nam%double_fit,mpl%ioproc-1)
765 call mpl%f_comm%broadcast(nam%lhomh,mpl%ioproc-1)
766 call mpl%f_comm%broadcast(nam%lhomv,mpl%ioproc-1)
767 call mpl%f_comm%broadcast(nam%rvflt,mpl%ioproc-1)
768 call mpl%f_comm%broadcast(nam%lct_nscales,mpl%ioproc-1)
769 call mpl%f_comm%broadcast(nam%lct_diag,mpl%ioproc-1)
770 
771 ! nicas_param
772 call mpl%f_comm%broadcast(nam%lsqrt,mpl%ioproc-1)
773 call mpl%f_comm%broadcast(nam%resol,mpl%ioproc-1)
774 call mpl%f_comm%broadcast(nam%fast_sampling,mpl%ioproc-1)
775 call mpl%f_comm%broadcast(nam%nicas_interp,mpl%ioproc-1)
776 call mpl%f_comm%broadcast(nam%network,mpl%ioproc-1)
777 call mpl%f_comm%broadcast(nam%mpicom,mpl%ioproc-1)
778 call mpl%f_comm%broadcast(nam%advmode,mpl%ioproc-1)
779 call mpl%f_comm%broadcast(nam%forced_radii,mpl%ioproc-1)
780 call mpl%f_comm%broadcast(nam%rh,mpl%ioproc-1)
781 call mpl%f_comm%broadcast(nam%rv,mpl%ioproc-1)
782 call mpl%f_comm%broadcast(nam%ndir,mpl%ioproc-1)
783 call mpl%f_comm%broadcast(nam%londir,mpl%ioproc-1)
784 call mpl%f_comm%broadcast(nam%latdir,mpl%ioproc-1)
785 call mpl%f_comm%broadcast(nam%levdir,mpl%ioproc-1)
786 call mpl%f_comm%broadcast(nam%ivdir,mpl%ioproc-1)
787 call mpl%f_comm%broadcast(nam%itsdir,mpl%ioproc-1)
788 
789 ! obsop_param
790 call mpl%f_comm%broadcast(nam%nobs,mpl%ioproc-1)
791 call mpl%f_comm%broadcast(nam%obsdis,mpl%ioproc-1)
792 call mpl%f_comm%broadcast(nam%obsop_interp,mpl%ioproc-1)
793 
794 ! output_param
795 call mpl%f_comm%broadcast(nam%nldwh,mpl%ioproc-1)
796 call mpl%f_comm%broadcast(nam%il_ldwh,mpl%ioproc-1)
797 call mpl%f_comm%broadcast(nam%ic_ldwh,mpl%ioproc-1)
798 call mpl%f_comm%broadcast(nam%nldwv,mpl%ioproc-1)
799 call mpl%f_comm%broadcast(nam%lon_ldwv,mpl%ioproc-1)
800 call mpl%f_comm%broadcast(nam%lat_ldwv,mpl%ioproc-1)
801 call mpl%f_comm%broadcast(nam%diag_rhflt,mpl%ioproc-1)
802 call mpl%f_comm%broadcast(nam%diag_interp,mpl%ioproc-1)
803 call mpl%f_comm%broadcast(nam%field_io,mpl%ioproc-1)
804 call mpl%f_comm%broadcast(nam%split_io,mpl%ioproc-1)
805 call mpl%f_comm%broadcast(nam%grid_output,mpl%ioproc-1)
806 call mpl%f_comm%broadcast(nam%grid_resol,mpl%ioproc-1)
807 call mpl%f_comm%broadcast(nam%grid_interp,mpl%ioproc-1)
808 
809 end subroutine nam_bcast
810 
811 !----------------------------------------------------------------------
812 ! Subroutine: nam_setup_internal
813 ! Purpose: setup namelist parameters internally (model 'online')
814 !----------------------------------------------------------------------
815 subroutine nam_setup_internal(nam,nl0,nv,nts,ens1_ne,ens1_nsub,ens2_ne,ens2_nsub)
817 implicit none
818 
819 ! Passed variable
820 class(nam_type),intent(inout) :: nam ! Namelist
821 integer,intent(in) :: nl0 ! Number of levels
822 integer,intent(in) :: nv ! Number of variables
823 integer,intent(in) :: nts ! Number of time-slots
824 integer,intent(in) :: ens1_ne ! Ensemble 1 size
825 integer,intent(in) :: ens1_nsub ! Ensemble 1 number of sub-ensembles
826 integer,intent(in) :: ens2_ne ! Ensemble 2 size
827 integer,intent(in) :: ens2_nsub ! Ensemble 2 size of sub-ensembles
828 
829 ! Local variables
830 integer :: il,iv
831 
832 if (trim(nam%datadir)=='') nam%datadir = '.'
833 nam%model = 'online'
834 nam%colorlog = .false.
835 nam%nl = nl0
836 do il=1,nam%nl
837  nam%levs(il) = il
838 end do
839 nam%logpres = .false.
840 nam%nv = nv
841 do iv=1,nam%nv
842  write(nam%varname(iv),'(a,i2.2)') 'var_',iv
843  nam%addvar2d(iv) = ''
844 end do
845 nam%nts = nts
846 nam%timeslot = 0
847 nam%ens1_ne = ens1_ne
848 nam%ens1_ne_offset = 0
849 nam%ens1_nsub = ens1_nsub
850 nam%ens2_ne = ens2_ne
851 nam%ens2_ne_offset = 0
852 nam%ens2_nsub = ens2_nsub
853 
854 end subroutine nam_setup_internal
855 
856 !----------------------------------------------------------------------
857 ! Subroutine: nam_check
858 ! Purpose: check namelist parameters
859 !----------------------------------------------------------------------
860 subroutine nam_check(nam,mpl)
862 implicit none
863 
864 ! Passed variable
865 class(nam_type),intent(inout) :: nam ! Namelist
866 type(mpl_type),intent(in) :: mpl ! MPI data
867 
868 ! Local variables
869 integer :: iv,its,il,idir
870 character(len=2) :: ivchar
871 
872 ! Check maximum sizes
873 if (nam%nl>nlmax) call mpl%abort('nl is too large')
874 if (nam%nv>nvmax) call mpl%abort('nv is too large')
875 if (nam%nts>ntsmax) call mpl%abort('nts is too large')
876 if (nam%nc3>nc3max) call mpl%abort('nc3 is too large')
877 if (nam%lct_nscales>nscalesmax) call mpl%abort('lct_nscales is too large')
878 if (nam%ndir>ndirmax) call mpl%abort('ndir is too large')
879 if (nam%nldwh>nlmax*nc3max) call mpl%abort('nldwh is too large')
880 if (nam%nldwv>nldwvmax) call mpl%abort('nldwv is too large')
881 
882 ! Namelist parameters normalization (meters to radians and degrees to radians)
883 nam%dc = nam%dc/req
884 nam%vbal_rad = nam%vbal_rad/req
885 nam%var_rhflt = nam%var_rhflt/req
886 nam%local_rad = nam%local_rad/req
887 nam%displ_rad = nam%displ_rad/req
888 nam%displ_rhflt = nam%displ_rhflt/req
889 nam%rh = nam%rh/req
890 if (nam%ndir>0) nam%londir(1:nam%ndir) = nam%londir(1:nam%ndir)*deg2rad
891 if (nam%ndir>0) nam%latdir(1:nam%ndir) = nam%latdir(1:nam%ndir)*deg2rad
892 if (nam%nldwv>0) nam%lon_ldwv(1:nam%nldwv) = nam%lon_ldwv(1:nam%nldwv)*deg2rad
893 if (nam%nldwv>0) nam%lat_ldwv(1:nam%nldwv) = nam%lat_ldwv(1:nam%nldwv)*deg2rad
894 nam%diag_rhflt = nam%diag_rhflt/req
895 nam%grid_resol = nam%grid_resol/req
896 
897 ! Check general_param
898 if (trim(nam%datadir)=='') call mpl%abort('datadir not specified')
899 if (trim(nam%prefix)=='') call mpl%abort('prefix not specified')
900 select case (trim(nam%model))
901 case ('aro','arp','fv3','gem','geos','gfs','ifs','mpas','nemo','online','wrf')
902 case default
903  call mpl%abort('wrong model')
904 end select
905 
906 ! Check driver_param
907 if (nam%new_hdiag.or.nam%check_consistency.or.nam%check_optimality) then
908  select case (trim(nam%method))
909  case ('cor','loc_norm','loc','hyb-avg','hyb-rnd','dual-ens')
910  case default
911  call mpl%abort('wrong method')
912  end select
913 end if
914 if (nam%new_lct) then
915  if (trim(nam%method)/='cor') call mpl%abort('new_lct requires cor method')
916 end if
917 if (nam%new_hdiag.or.nam%new_lct.or.nam%load_cmat.or.nam%new_nicas.or.nam%load_nicas) then
918  select case (trim(nam%strategy))
919  case ('diag_all','common','common_univariate','common_weighted','specific_univariate')
920  case ('specific_multivariate')
921  if (.not.nam%lsqrt) call mpl%abort('specific multivariate strategy requires a square-root formulation')
922  case default
923  call mpl%abort('wrong strategy')
924  end select
925 end if
926 if (nam%new_vbal.and.nam%load_vbal) call mpl%abort('new_vbal and load_vbal are exclusive')
927 if (nam%new_hdiag.and.nam%new_lct) call mpl%abort('new_hdiag and new_lct are exclusive')
928 if ((nam%new_hdiag.or.nam%new_lct).and.nam%load_cmat) call mpl%abort('new_hdiag or new_lct and load_cmat are exclusive')
929 if (nam%new_nicas.and.nam%load_nicas) call mpl%abort('new_nicas and load_nicas are exclusive')
930 if (nam%new_obsop.and.nam%load_obsop) call mpl%abort('new_obsop and load_obsop are exclusive')
931 if (nam%check_vbal.and..not.(nam%new_vbal.or.nam%load_vbal)) call mpl%abort('check_vbal requires new_vbal or load_vbal')
932 if (nam%new_nicas.and..not.(nam%new_hdiag.or.nam%new_lct.or.nam%load_cmat.or.nam%forced_radii)) &
933  & call mpl%abort('new_nicas requires a C matrix')
934 if (nam%check_adjoints.and..not.(nam%new_nicas.or.nam%load_nicas)) call mpl%abort('check_adjoint requires new_nicas or load_nicas')
935 if (nam%check_pos_def.and..not.(nam%new_nicas.or.nam%load_nicas)) call mpl%abort('check_pos_def requires new_nicas or load_nicas')
936 if (nam%check_sqrt.and..not.(nam%new_nicas.or.nam%load_nicas)) call mpl%abort('check_sqrt requires new_nicas or load_nicas')
937 if (nam%check_dirac.and..not.(nam%new_nicas.or.nam%load_nicas)) call mpl%abort('check_dirac requires new_nicas or load_nicas')
938 if (nam%check_randomization.and..not.(nam%new_nicas.or.nam%load_nicas)) &
939  & call mpl%abort('check_randomization requires new_nicas or load_nicas')
940 if (nam%check_consistency.and..not.((nam%new_hdiag.or.nam%load_cmat).and.nam%new_nicas)) &
941  & call mpl%abort('check_adjoint requires new_nicas or load_nicas and new_nicas')
942 if (nam%check_optimality.and..not.(nam%new_nicas.or.nam%load_nicas)) &
943  & call mpl%abort('check_optimality requires new_nicas or load_nicas')
944 if (nam%check_obsop.and..not.(nam%new_obsop.or.nam%load_obsop)) call mpl%abort('check_obsop requires new_obsop or load_obsop')
945 
946 ! Check model_param
947 if (nam%nl<=0) call mpl%abort('nl should be positive')
948 do il=1,nam%nl
949  if (nam%levs(il)<=0) call mpl%abort('levs should be positive')
950  if (count(nam%levs(1:nam%nl)==nam%levs(il))>1) call mpl%abort('redundant levels')
951 end do
952 if (nam%logpres) then
953  select case (trim(nam%model))
954  case ('nemo')
955  call mpl%warning('pressure logarithm vertical coordinate is not available for this model, resetting to model level index')
956  nam%logpres = .false.
957  end select
958 end if
959 if (nam%new_vbal.or.nam%load_vbal.or.nam%new_hdiag.or.nam%new_lct.or.nam%load_cmat.or.nam%new_nicas.or.nam%load_nicas) then
960  if (nam%nv<=0) call mpl%abort('nv should be positive')
961  do iv=1,nam%nv
962  write(ivchar,'(i2.2)') iv
963  if (trim(nam%varname(iv))=='') call mpl%abort('varname not specified for variable '//ivchar)
964  end do
965  if (nam%nts<=0) call mpl%abort('nts should be positive')
966  do its=1,nam%nts
967  if (nam%timeslot(its)<0) call mpl%abort('timeslot should be non-negative')
968  end do
969  do iv=1,nam%nv
970  if (trim(nam%addvar2d(iv))/='') nam%levs(nam%nl+1) = maxval(nam%levs(1:nam%nl))+1
971  end do
972 end if
973 
974 ! Check ens1_param
975 if (nam%new_vbal.or.nam%new_hdiag.or.nam%new_lct) then
976  if (nam%ens1_ne_offset<0) call mpl%abort('ens1_ne_offset should be non-negative')
977  if (nam%ens1_nsub<1) call mpl%abort('ens1_nsub should be positive')
978  if (mod(nam%ens1_ne,nam%ens1_nsub)/=0) call mpl%abort('ens1_nsub should be a divider of ens1_ne')
979  if (nam%ens1_ne/nam%ens1_nsub<=3) call mpl%abort('ens1_ne/ens1_nsub should be larger than 3')
980 end if
981 
982 ! Check ens2_param
983 if (nam%new_hdiag) then
984  select case (trim(nam%method))
985  case ('hyb-rnd','dual-ens')
986  if (nam%ens2_ne_offset<0) call mpl%abort('ens2_ne_offset should be non-negative')
987  if (nam%ens2_nsub<1) call mpl%abort('ens2_nsub should be non-negative')
988  if (mod(nam%ens2_ne,nam%ens2_nsub)/=0) call mpl%abort('ens2_nsub should be a divider of ens2_ne')
989  if (nam%ens2_ne/nam%ens2_nsub<=3) call mpl%abort('ens2_ne/ens2_nsub should be larger than 3')
990  end select
991 end if
992 
993 ! Check sampling_param
994 if (nam%new_vbal.or.nam%new_hdiag.or.nam%new_lct) then
995  if (nam%sam_write.and.nam%sam_read) call mpl%abort('sam_write and sam_read are both true')
996  select case (trim(nam%draw_type))
997  case ('random_uniform','random_coast','icosahedron')
998  case default
999  call mpl%abort('wrong draw_type')
1000  end select
1001  if (nam%nc1<3) call mpl%abort('nc1 should be larger than 2')
1002  if (nam%new_vbal.or.(nam%new_hdiag.and.(nam%var_diag.or.nam%local_diag.or.nam%displ_diag))) then
1003  if (nam%nc2<3) call mpl%abort('nc2 should be larger than 2')
1004  else
1005  if (nam%nc2<0) then
1006  call mpl%warning('nc2 should be set non-negative, resetting nc2 to zero')
1007  nam%nc2 = 0
1008  end if
1009  end if
1010  if (nam%new_lct) then
1011  if (nam%nc2/=nam%nc1) then
1012  call mpl%warning('nc2 should be equal to nc2 for new_lct, resetting nc2 to nc1')
1013  nam%nc2 = nam%nc1
1014  end if
1015  end if
1016 end if
1017 if (nam%new_vbal.or.nam%new_hdiag.or.nam%new_lct.or.nam%new_nicas) then
1018  if (nam%ntry<=0) call mpl%abort('ntry should be positive')
1019  if (nam%nrep<0) call mpl%abort('nrep should be non-negative')
1020 end if
1021 if (nam%new_hdiag.or.nam%new_lct) then
1022  if (nam%nc3<=0) call mpl%abort('nc3 should be positive')
1023 else
1024  nam%nc3 = 1
1025 end if
1026 if (nam%new_vbal.or.nam%load_vbal.or.nam%new_hdiag.or.nam%new_lct) then
1027  if (nam%nl0r<1) call mpl%abort ('nl0r should be positive')
1028 end if
1029 if (nam%new_hdiag) then
1030  if (nam%dc<0.0) call mpl%abort('dc should be positive')
1031 end if
1032 
1033 ! Check diag_param
1034 if (nam%new_vbal) then
1035  if (nam%nv<2) call mpl%abort('at least two variables required to diagnose vertical balance')
1036  if (.not.(any(nam%vbal_block(1:nam%nv*(nam%nv-1)/2)))) &
1037  & call mpl%abort('no block selected for the vertical balance diagnostics')
1038 
1039  if (nam%vbal_rad<0.0) call mpl%abort('vbal_rad should be non-negative')
1040 end if
1041 if (nam%new_hdiag) then
1042  select case (trim(nam%method))
1043  case ('loc_norm','loc','hyb-avg','hyb-rnd','dual-ens')
1044  if (nam%ne<=3) call mpl%abort('ne should be larger than 3')
1045  end select
1046  if (nam%var_diag.and.(.not.trim(nam%method)=='cor')) call mpl%abort('var_diag requires method = cor')
1047  if (nam%var_filter.and.(.not.nam%var_diag)) call mpl%abort('var_filter requires var_diag')
1048  if (nam%var_filter) then
1049  if (nam%var_niter<=0) call mpl%abort('var_niter should be positive')
1050  if (nam%var_rhflt<0.0) call mpl%abort('var_rhflt should be non-negative')
1051  end if
1052  if (nam%local_diag) then
1053  if (nam%local_rad<0.0) call mpl%abort('displ_rad should be non-negative')
1054  end if
1055  if (nam%displ_diag) then
1056  if (nam%displ_rad<0.0) call mpl%abort('local_rad should be non-negative')
1057  if (nam%displ_niter<=0) call mpl%abort('displ_niter should be positive')
1058  if (nam%displ_rhflt<0.0) call mpl%abort('displ_rhflt should be non-negative')
1059  if (nam%displ_tol<0.0) call mpl%abort('displ_tol should be non-negative')
1060  end if
1061 end if
1062 
1063 ! Check fit_param
1064 if (nam%new_hdiag.or.nam%new_lct) then
1065  select case (trim(nam%minim_algo))
1066  case ('none','fast','hooke')
1067  case default
1068  call mpl%abort('wrong minim_algo')
1069  end select
1070  if (nam%new_lct.and.((trim(nam%minim_algo)=='none').or.(trim(nam%minim_algo)=='fast'))) &
1071  & call mpl%abort('wrong minim_algo for LCT')
1072  if (nam%rvflt<0) call mpl%abort('rvflt should be non-negative')
1073 end if
1074 if (nam%new_lct) then
1075  if (nam%lct_nscales<=0) call mpl%abort('lct_nscales should be postive')
1076 end if
1077 
1078 ! Check ensemble sizes
1079 if (nam%new_hdiag) then
1080  if (trim(nam%method)/='cor') then
1081  if (nam%ne>nam%ens1_ne) call mpl%warning('ensemble size larger than ens1_ne (might enhance sampling noise)')
1082  select case (trim(nam%method))
1083  case ('hyb-avg','hyb-rnd','dual-ens')
1084  if (nam%ne>nam%ens2_ne) call mpl%warning('ensemble size larger than ens2_ne (might enhance sampling noise)')
1085  end select
1086  end if
1087 end if
1088 
1089 ! Check nicas_param
1090 if (nam%new_nicas.or.nam%check_adjoints.or.nam%check_pos_def.or.nam%check_sqrt.or.nam%check_dirac.or.nam%check_randomization &
1091  & .or.nam%check_consistency.or.nam%check_optimality) then
1092  if (nam%lsqrt) then
1093  if (nam%mpicom==1) call mpl%abort('mpicom should be 2 for square-root application')
1094  end if
1095  if (nam%check_randomization) then
1096  if (.not.nam%lsqrt) call mpl%abort('lsqrt required for check_randomization')
1097  end if
1098  if (nam%check_consistency) then
1099  if (.not.nam%lsqrt) call mpl%abort('lsqrt required for check_consistency')
1100  end if
1101  if (nam%check_optimality) then
1102  if (.not.nam%lsqrt) call mpl%abort('lsqrt required for check_optimality')
1103  end if
1104  if (nam%new_nicas) then
1105  if (.not.(nam%resol>0.0)) call mpl%abort('resol should be positive')
1106  end if
1107  if (nam%new_nicas.or.nam%load_nicas) then
1108  if ((nam%mpicom/=1).and.(nam%mpicom/=2)) call mpl%abort('mpicom should be 1 or 2')
1109  end if
1110  if (nam%forced_radii) then
1111  if (nam%new_hdiag.or.nam%new_lct.or.nam%load_cmat) &
1112  & call mpl%abort('forced_radii requires new_hdiag, new_lct and load_cmat to be inactive')
1113  if (nam%rh<0.0) call mpl%abort('rh should be non-negative')
1114  if (nam%rv<0.0) call mpl%abort('rv should be non-negative')
1115  end if
1116  if (abs(nam%advmode)>1) call mpl%abort('nam%advmode should be -1, 0 or 1')
1117  if (nam%check_dirac) then
1118  if (nam%ndir<1) call mpl%abort('ndir should be positive')
1119  do idir=1,nam%ndir
1120  if ((nam%londir(idir)<-180.0).or.(nam%londir(idir)>180.0)) &
1121  & call mpl%abort('Dirac longitude should lie between -180 and 180')
1122  if ((nam%latdir(idir)<-90.0).or.(nam%latdir(idir)>90.0)) call mpl%abort('Dirac latitude should lie between -90 and 90')
1123  if (.not.(any(nam%levs(1:nam%nl)==nam%levdir(idir)).or.(any(nam%addvar2d(1:nam%nv)/='') &
1124  & .and.(nam%levs(nam%nl+1)==nam%levdir(idir))))) call mpl%abort('wrong level for a Dirac')
1125  if ((nam%ivdir(idir)<1).or.(nam%ivdir(idir)>nam%nv)) call mpl%abort('wrong variable for a Dirac')
1126  if ((nam%itsdir(idir)<1).or.(nam%itsdir(idir)>nam%nts)) call mpl%abort('wrong timeslot for a Dirac')
1127  end do
1128  end if
1129  select case (trim(nam%nicas_interp))
1130  case ('bilin','natural')
1131  case default
1132  call mpl%abort('wrong interpolation for NICAS')
1133  end select
1134 end if
1135 
1136 ! Check obsop_param
1137 if (nam%new_obsop) then
1138  select case (trim(nam%obsdis))
1139  case('')
1140  case ('random','local','adjusted')
1141  if (trim(nam%model)=='online') call mpl%abort('modified distribution of observations only available for offline execution')
1142  case default
1143  call mpl%abort('wrong observation distribution')
1144  end select
1145  select case (trim(nam%obsop_interp))
1146  case ('bilin','natural')
1147  case default
1148  call mpl%abort('wrong interpolation for observation operator')
1149  end select
1150 end if
1151 
1152 ! Check output_param
1153 if (nam%new_hdiag) then
1154  if (nam%local_diag) then
1155  if (nam%nldwh<0) call mpl%abort('nldwh should be non-negative')
1156  if (nam%nldwh>0) then
1157  if (any(nam%il_ldwh(1:nam%nldwh)<0)) call mpl%abort('il_ldwh should be non-negative')
1158  if (any(nam%il_ldwh(1:nam%nldwh)>nam%nl)) call mpl%abort('il_ldwh should be lower than nl')
1159  if (any(nam%ic_ldwh(1:nam%nldwh)<0)) call mpl%abort('ic_ldwh should be non-negative')
1160  if (any(nam%ic_ldwh(1:nam%nldwh)>nam%nc3)) call mpl%abort('ic_ldwh should be lower than nc3')
1161  end if
1162  if (nam%nldwv<0) call mpl%abort('nldwv should be non-negative')
1163  if (nam%nldwv>0) then
1164  if (any(nam%lon_ldwv(1:nam%nldwv)<-180.0).or.any(nam%lon_ldwv(1:nam%nldwv)>180.0)) call mpl%abort('wrong lon_ldwv')
1165  if (any(nam%lat_ldwv(1:nam%nldwv)<-90.0).or.any(nam%lat_ldwv(1:nam%nldwv)>90.0)) call mpl%abort('wrong lat_ldwv')
1166  end if
1167  end if
1168  if (nam%local_diag.or.nam%displ_diag) then
1169  if (nam%diag_rhflt<0.0) call mpl%abort('diag_rhflt should be non-negative')
1170  end if
1171 end if
1172 if (nam%new_hdiag.or.nam%new_lct) then
1173  select case (trim(nam%diag_interp))
1174  case ('bilin','natural')
1175  case default
1176  call mpl%abort('wrong interpolation for diagnostics')
1177  end select
1178 end if
1179 if (nam%new_hdiag.or.nam%new_nicas.or.nam%check_adjoints.or.nam%check_pos_def.or.nam%check_sqrt.or.nam%check_dirac &
1180  & .or.nam%check_randomization.or.nam%check_consistency.or.nam%check_optimality.or.nam%new_lct) then
1181  if (nam%grid_output) then
1182  if (.not.(nam%grid_resol>0.0)) call mpl%abort('grid_resol should be positive')
1183  select case (trim(nam%grid_interp))
1184  case ('bilin','natural')
1185  case default
1186  call mpl%abort('wrong interpolation for fields regridding')
1187  end select
1188  end if
1189 end if
1190 
1191 end subroutine nam_check
1192 
1193 !----------------------------------------------------------------------
1194 ! Subroutine: nam_ncwrite
1195 ! Purpose: write namelist parameters as NetCDF attributes
1196 !----------------------------------------------------------------------
1197 subroutine nam_ncwrite(nam,mpl,ncid)
1199 implicit none
1200 
1201 ! Passed variable
1202 class(nam_type),intent(in) :: nam ! Namelist
1203 type(mpl_type),intent(in) :: mpl ! MPI data
1204 integer,intent(in) :: ncid ! NetCDF file ID
1205 
1206 ! Local variables
1207 real(kind_real),allocatable :: londir(:),latdir(:),lon_ldwv(:),lat_ldwv(:)
1208 
1209 ! general_param
1210 call put_att(mpl,ncid,'datadir',trim(nam%datadir))
1211 call put_att(mpl,ncid,'prefix',trim(nam%prefix))
1212 call put_att(mpl,ncid,'model',trim(nam%model))
1213 call put_att(mpl,ncid,'colorlog',nam%colorlog)
1214 call put_att(mpl,ncid,'default_seed',nam%default_seed)
1215 
1216 ! driver_param
1217 call put_att(mpl,ncid,'method',trim(nam%method))
1218 call put_att(mpl,ncid,'strategy',trim(nam%strategy))
1219 call put_att(mpl,ncid,'new_vbal',nam%new_vbal)
1220 call put_att(mpl,ncid,'load_vbal',nam%load_vbal)
1221 call put_att(mpl,ncid,'new_hdiag',nam%new_hdiag)
1222 call put_att(mpl,ncid,'new_lct',nam%new_lct)
1223 call put_att(mpl,ncid,'load_cmat',nam%load_cmat)
1224 call put_att(mpl,ncid,'new_nicas',nam%new_nicas)
1225 call put_att(mpl,ncid,'load_nicas',nam%load_nicas)
1226 call put_att(mpl,ncid,'new_obsop',nam%new_obsop)
1227 call put_att(mpl,ncid,'load_obsop',nam%load_obsop)
1228 call put_att(mpl,ncid,'check_vbal',nam%check_vbal)
1229 call put_att(mpl,ncid,'check_adjoints',nam%check_adjoints)
1230 call put_att(mpl,ncid,'check_pos_def',nam%check_pos_def)
1231 call put_att(mpl,ncid,'check_sqrt',nam%check_sqrt)
1232 call put_att(mpl,ncid,'check_dirac',nam%check_dirac)
1233 call put_att(mpl,ncid,'check_randomization',nam%check_randomization)
1234 call put_att(mpl,ncid,'check_consistency',nam%check_consistency)
1235 call put_att(mpl,ncid,'check_optimality',nam%check_optimality)
1236 call put_att(mpl,ncid,'check_obsop',nam%check_obsop)
1237 
1238 ! model_param
1239 call put_att(mpl,ncid,'nl',nam%nl)
1240 call put_att(mpl,ncid,'levs',nam%nl,nam%levs(1:nam%nl))
1241 call put_att(mpl,ncid,'logpres',nam%logpres)
1242 call put_att(mpl,ncid,'nv',nam%nv)
1243 call put_att(mpl,ncid,'varname',nam%nv,nam%varname(1:nam%nv))
1244 call put_att(mpl,ncid,'addvar2d',nam%nv,nam%addvar2d(1:nam%nv))
1245 call put_att(mpl,ncid,'nts',nam%nts)
1246 call put_att(mpl,ncid,'timeslot',nam%nts,nam%timeslot(1:nam%nts))
1247 
1248 ! ens1_param
1249 call put_att(mpl,ncid,'ens1_ne',nam%ens1_ne)
1250 call put_att(mpl,ncid,'ens1_ne_offset',nam%ens1_ne_offset)
1251 call put_att(mpl,ncid,'ens1_nsub',nam%ens1_nsub)
1252 
1253 ! ens2_param
1254 call put_att(mpl,ncid,'ens2_ne',nam%ens2_ne)
1255 call put_att(mpl,ncid,'ens2_ne_offset',nam%ens2_ne_offset)
1256 call put_att(mpl,ncid,'ens2_nsub',nam%ens2_nsub)
1257 
1258 ! sampling_param
1259 call put_att(mpl,ncid,'sam_write',nam%sam_write)
1260 call put_att(mpl,ncid,'sam_read',nam%sam_read)
1261 call put_att(mpl,ncid,'mask_type',nam%mask_type)
1262 call put_att(mpl,ncid,'mask_th',nam%mask_th)
1263 call put_att(mpl,ncid,'mask_check',nam%mask_check)
1264 call put_att(mpl,ncid,'draw_type',nam%draw_type)
1265 call put_att(mpl,ncid,'nc1',nam%nc1)
1266 call put_att(mpl,ncid,'ntry',nam%ntry)
1267 call put_att(mpl,ncid,'nrep',nam%nrep)
1268 call put_att(mpl,ncid,'nc3',nam%nc3)
1269 call put_att(mpl,ncid,'dc',nam%dc*req)
1270 call put_att(mpl,ncid,'nl0r',nam%nl0r)
1271 
1272 ! vbal_param
1273 if (nam%nv>1) call put_att(mpl,ncid,'vbal_block',nam%nv*(nam%nv-1)/2,nam%vbal_block(1:nam%nv*(nam%nv-1)/2))
1274 
1275 ! diag_param
1276 call put_att(mpl,ncid,'ne',nam%ne)
1277 call put_att(mpl,ncid,'gau_approx',nam%gau_approx)
1278 call put_att(mpl,ncid,'var_diag',nam%var_diag)
1279 call put_att(mpl,ncid,'var_filter',nam%var_filter)
1280 call put_att(mpl,ncid,'var_full',nam%var_full)
1281 call put_att(mpl,ncid,'var_niter',nam%var_niter)
1282 call put_att(mpl,ncid,'var_rhflt',nam%var_rhflt*req)
1283 call put_att(mpl,ncid,'local_diag',nam%local_diag)
1284 call put_att(mpl,ncid,'local_rad',nam%local_rad*req)
1285 call put_att(mpl,ncid,'displ_diag',nam%displ_diag)
1286 call put_att(mpl,ncid,'displ_rad',nam%displ_rad*req)
1287 call put_att(mpl,ncid,'displ_niter',nam%displ_niter)
1288 call put_att(mpl,ncid,'displ_rhflt',nam%displ_rhflt*req)
1289 call put_att(mpl,ncid,'displ_tol',nam%displ_tol)
1290 
1291 ! fit_param
1292 call put_att(mpl,ncid,'minim_algo',nam%minim_algo)
1293 call put_att(mpl,ncid,'double_fit',nam%nv+1,nam%double_fit(0:nam%nv))
1294 call put_att(mpl,ncid,'lhomh',nam%lhomh)
1295 call put_att(mpl,ncid,'lhomv',nam%lhomv)
1296 call put_att(mpl,ncid,'rvflt',nam%rvflt)
1297 call put_att(mpl,ncid,'lct_nscales',nam%lct_nscales)
1298 call put_att(mpl,ncid,'lct_diag',nam%lct_nscales,nam%lct_diag)
1299 
1300 ! nicas_param
1301 call put_att(mpl,ncid,'lsqrt',nam%lsqrt)
1302 call put_att(mpl,ncid,'resol',nam%resol)
1303 call put_att(mpl,ncid,'fast_sampling',nam%fast_sampling)
1304 call put_att(mpl,ncid,'nicas_interp',nam%nicas_interp)
1305 call put_att(mpl,ncid,'network',nam%network)
1306 call put_att(mpl,ncid,'mpicom',nam%mpicom)
1307 call put_att(mpl,ncid,'advmode',nam%advmode)
1308 call put_att(mpl,ncid,'ndir',nam%ndir)
1309 if (nam%ndir>0) then
1310  allocate(londir(nam%ndir))
1311  allocate(latdir(nam%ndir))
1312  londir = nam%londir(1:nam%ndir)*rad2deg
1313  latdir = nam%latdir(1:nam%ndir)*rad2deg
1314  call put_att(mpl,ncid,'londir',nam%ndir,londir)
1315  call put_att(mpl,ncid,'latdir',nam%ndir,latdir)
1316  call put_att(mpl,ncid,'levdir',nam%ndir,nam%levdir(1:nam%ndir))
1317  call put_att(mpl,ncid,'ivdir',nam%ndir,nam%ivdir(1:nam%ndir))
1318  call put_att(mpl,ncid,'itsdir',nam%ndir,nam%itsdir(1:nam%ndir))
1319 end if
1320 
1321 ! obsop_param
1322 call put_att(mpl,ncid,'nobs',nam%nobs)
1323 call put_att(mpl,ncid,'obsdis',nam%obsdis)
1324 call put_att(mpl,ncid,'obsop_interp',nam%obsop_interp)
1325 
1326 ! output_param
1327 call put_att(mpl,ncid,'nldwh',nam%nldwh)
1328 if (nam%nldwh>0) then
1329  call put_att(mpl,ncid,'il_ldwh',nam%nldwh,nam%il_ldwh(1:nam%nldwh))
1330  call put_att(mpl,ncid,'ic_ldwh',nam%nldwh,nam%ic_ldwh(1:nam%nldwh))
1331 end if
1332 call put_att(mpl,ncid,'nldwv',nam%nldwv)
1333 if (nam%nldwv>0) then
1334  allocate(lon_ldwv(nam%nldwv))
1335  allocate(lat_ldwv(nam%nldwv))
1336  lon_ldwv = nam%lon_ldwv(1:nam%nldwv)*rad2deg
1337  lat_ldwv = nam%lat_ldwv(1:nam%nldwv)*rad2deg
1338  call put_att(mpl,ncid,'lon_ldwv',nam%nldwv,lon_ldwv)
1339  call put_att(mpl,ncid,'lat_ldwv',nam%nldwv,lat_ldwv)
1340 end if
1341 call put_att(mpl,ncid,'diag_rhflt',nam%diag_rhflt*req)
1342 call put_att(mpl,ncid,'diag_interp',nam%diag_interp)
1343 call put_att(mpl,ncid,'field_io',nam%field_io)
1344 call put_att(mpl,ncid,'split_io',nam%split_io)
1345 call put_att(mpl,ncid,'grid_output',nam%grid_output)
1346 call put_att(mpl,ncid,'grid_resol',nam%grid_resol*req)
1347 call put_att(mpl,ncid,'grid_interp',nam%grid_interp)
1348 
1349 end subroutine nam_ncwrite
1350 
1351 end module type_nam
real(kind_real), parameter, public rad2deg
Definition: tools_const.F90:17
subroutine check(action, status)
subroutine nam_read(nam, mpl, namelname)
Definition: type_nam.F90:329
integer, parameter, public nlmax
Definition: type_nam.F90:23
subroutine nam_init(nam)
Definition: type_nam.F90:178
subroutine nam_ncwrite(nam, mpl, ncid)
Definition: type_nam.F90:1198
integer, parameter, public nldwvmax
Definition: type_nam.F90:27
real(kind_real), parameter, public deg2rad
Definition: tools_const.F90:16
real(kind=kind_real), parameter req
Earth radius at equator (m)
subroutine nam_bcast(nam, mpl)
Definition: type_nam.F90:673
integer, parameter, public ntsmax
Definition: type_nam.F90:22
integer, parameter, public nc3max
Definition: type_nam.F90:24
integer, parameter, public nvmax
Definition: type_nam.F90:21
subroutine nam_setup_internal(nam, nl0, nv, nts, ens1_ne, ens1_nsub, ens2_ne, ens2_nsub)
Definition: type_nam.F90:816
integer, parameter, public ndirmax
Definition: type_nam.F90:26
integer, parameter, public nscalesmax
Definition: type_nam.F90:25
integer, parameter, public kind_real
subroutine nam_check(nam, mpl)
Definition: type_nam.F90:861