24 module ensemble_manager_mod
30 use mpp_mod,
only : input_nml_file
31 use fms2_io_mod,
only : fms2_io_set_filename_appendix=>set_filename_appendix
37 integer,
parameter :: MAX_ENSEMBLE_SIZE = 100
40 integer,
allocatable,
dimension(:,:) :: ensemble_pelist
41 integer,
allocatable,
dimension(:,:) :: ensemble_pelist_ocean
42 integer,
allocatable,
dimension(:,:) :: ensemble_pelist_atmos
43 integer,
allocatable,
dimension(:,:) :: ensemble_pelist_land
44 integer,
allocatable,
dimension(:,:) :: ensemble_pelist_ice
45 integer,
allocatable,
dimension(:) :: ensemble_pelist_ocean_filter
46 integer,
allocatable,
dimension(:) :: ensemble_pelist_atmos_filter
47 integer,
allocatable,
dimension(:) :: ensemble_pelist_land_filter
48 integer,
allocatable,
dimension(:) :: ensemble_pelist_ice_filter
50 integer :: ensemble_size = 1
51 integer :: ensemble_id = 1
72 integer :: pe, total_npes_pm=0,ocean_npes_pm=0,atmos_npes_pm=0
73 integer :: land_npes_pm=0,ice_npes_pm=0
96 integer :: i, io_status, npes, ierr
104 read (input_nml_file, ensemble_nml, iostat=io_status)
107 if(ensemble_size < 1)
call mpp_error(fatal, &
108 'ensemble_manager_mod: ensemble_nml variable ensemble_size must be a positive integer')
109 if(ensemble_size > max_ensemble_size)
call mpp_error(fatal, &
110 'ensemble_manager_mod: ensemble_nml variable ensemble_size should be no larger than MAX_ENSEMBLE_SIZE, '// &
111 'change ensemble_size or increase MAX_ENSEMBLE_SIZE')
113 'ensemble_manager_mod: ensemble_nml variable starting_ensemble_id must be a positive integer')
117 if (npes < ensemble_size)
then
118 call mpp_error(fatal,
'npes must be >= ensemble_size')
120 total_npes_pm = npes/ensemble_size
121 if (mod(npes, total_npes_pm) /= 0)
call mpp_error(fatal,
'ensemble_size must be divis by npes')
152 integer,
intent(inout) :: pelist(:,:)
153 character(len=*),
intent(in),
optional :: name
155 if (
size(pelist,1) < ensemble_size) &
156 call mpp_error(fatal,
'get_ensemble_pelist: size of pelist 1st index < ensemble_size')
158 if(
present(name))
then
161 if (
size(pelist,2) < ocean_npes_pm)&
162 call mpp_error(fatal,
'get_ensemble_pelist: size of pelist 2nd index < ocean_npes_pm')
164 pelist(1:ensemble_size,1:ocean_npes_pm) = &
165 ensemble_pelist_ocean(1:ensemble_size,1:ocean_npes_pm)
168 if (
size(pelist,2) < atmos_npes_pm)&
169 call mpp_error(fatal,
'get_ensemble_pelist: size of pelist 2nd index < atmos_npes_pm')
171 pelist(1:ensemble_size,1:atmos_npes_pm) = &
172 ensemble_pelist_atmos(1:ensemble_size,1:atmos_npes_pm)
175 if (
size(pelist,2) < land_npes_pm)&
176 call mpp_error(fatal,
'get_ensemble_pelist: size of pelist 2nd index < land_npes_pm')
178 pelist(1:ensemble_size,1:land_npes_pm) = &
179 ensemble_pelist_land(1:ensemble_size,1:land_npes_pm)
182 if (
size(pelist,2) < ice_npes_pm)&
183 call mpp_error(fatal,
'get_ensemble_pelist: size of pelist 2nd index < ice_npes_pm')
185 pelist(1:ensemble_size,1:ice_npes_pm) = &
186 ensemble_pelist_ice(1:ensemble_size,1:ice_npes_pm)
189 call mpp_error(fatal,
'get_ensemble_pelist: unknown argument name='//name)
192 if (
size(pelist,2) < total_npes_pm)&
193 call mpp_error(fatal,
'get_ensemble_pelist: size of pelist 2nd index < total_npes_pm')
195 pelist(1:ensemble_size,1:total_npes_pm) = &
196 ensemble_pelist(1:ensemble_size,1:total_npes_pm)
211 integer,
intent(inout) :: pelist(:)
212 character(len=*),
intent(in) :: name
216 if (
size(pelist) < ensemble_size * ocean_npes_pm)&
217 call mpp_error(fatal,
'get_ensemble_filter_pelist: size of pelist argument < ensemble_size * ocean_npes_pm')
219 pelist(1:ensemble_size*ocean_npes_pm) = &
220 ensemble_pelist_ocean_filter(1:ensemble_size*ocean_npes_pm)
223 if (
size(pelist) < ensemble_size * atmos_npes_pm)&
224 call mpp_error(fatal,
'get_ensemble_filter_pelist: size of pelist argument < ensemble_size * atmos_npes_pm')
226 pelist(1:ensemble_size*atmos_npes_pm) = &
227 ensemble_pelist_atmos_filter(1:ensemble_size*atmos_npes_pm)
230 if (
size(pelist) < ensemble_size * land_npes_pm)&
231 call mpp_error(fatal,
'get_ensemble_filter_pelist: size of pelist argument < ensemble_size * land_npes_pm')
233 pelist(1:ensemble_size*land_npes_pm) = &
234 ensemble_pelist_land_filter(1:ensemble_size*land_npes_pm)
237 if (
size(pelist) < ensemble_size * ice_npes_pm)&
238 call mpp_error(fatal,
'get_ensemble_filter_pelist: size of pelist argument < ensemble_size * ice_npes_pm')
240 pelist(1:ensemble_size*ice_npes_pm) = &
241 ensemble_pelist_ice_filter(1:ensemble_size*ice_npes_pm)
244 call mpp_error(fatal,
'get_ensemble_filter_pelist: unknown argument name='//name)
258 Atm_pelist, Ocean_pelist, Land_pelist, Ice_pelist)
259 logical,
intent(in) :: concurrent
260 integer,
intent(in) :: atmos_npes, ocean_npes
261 integer,
intent(in) :: land_npes, ice_npes
262 integer,
dimension(:),
intent(inout) :: atm_pelist, ocean_pelist
263 integer,
dimension(:),
intent(inout) :: land_pelist, ice_pelist
264 integer :: atmos_pe_start, atmos_pe_end, ocean_pe_start, ocean_pe_end
265 integer :: land_pe_start, land_pe_end, ice_pe_start, ice_pe_end
266 character(len=10) :: pelist_name, text
267 integer :: npes, n, m ,i, global_ens
272 if(land_npes > atmos_npes)
call mpp_error(fatal,
'ensemble_manager_mod: land_npes > atmos_npes')
273 if(ice_npes > atmos_npes)
call mpp_error(fatal,
'ensemble_manager_mod: ice_npes > atmos_npes')
275 allocate(ensemble_pelist(ensemble_size,total_npes_pm))
276 allocate(ensemble_pelist_ocean(1:ensemble_size, 1:ocean_npes) )
277 allocate(ensemble_pelist_atmos(1:ensemble_size, 1:atmos_npes) )
278 allocate(ensemble_pelist_land(1:ensemble_size, 1:land_npes) )
279 allocate(ensemble_pelist_ice(1:ensemble_size, 1:ice_npes) )
285 if( concurrent .OR. atmos_npes+ocean_npes == npes )
then
286 ocean_pe_start = ensemble_size*atmos_npes
289 atmos_pe_end = atmos_pe_start + atmos_npes - 1
290 ocean_pe_end = ocean_pe_start + ocean_npes - 1
291 land_pe_end = land_pe_start + land_npes - 1
292 ice_pe_end = ice_pe_start + ice_npes - 1
293 ensemble_pelist_atmos(n, 1:atmos_npes) = (/(i,i=atmos_pe_start,atmos_pe_end)/)
294 ensemble_pelist_ocean(n, 1:ocean_npes) = (/(i,i=ocean_pe_start,ocean_pe_end)/)
295 ensemble_pelist_land(n, 1:land_npes) = (/(i,i=land_pe_start, land_pe_end)/)
296 ensemble_pelist_ice(n, 1:ice_npes) = (/(i,i=ice_pe_start, ice_pe_end)/)
297 ensemble_pelist(n, 1:atmos_npes) = ensemble_pelist_atmos(n, 1:atmos_npes)
298 if( concurrent .OR. atmos_npes+ocean_npes == npes ) &
299 ensemble_pelist(n, atmos_npes+1:npes) = ensemble_pelist_ocean(n, 1:ocean_npes)
300 if(any(ensemble_pelist(n,:) == pe)) ensemble_id = n
301 write(pelist_name,
'(a,i2.2)')
'_ens',n
303 atmos_pe_start = atmos_pe_end + 1
304 ocean_pe_start = ocean_pe_end + 1
305 land_pe_start = atmos_pe_start
306 ice_pe_start = atmos_pe_start
309 atm_pelist(:) = ensemble_pelist_atmos(ensemble_id,:)
310 ocean_pelist(:) = ensemble_pelist_ocean(ensemble_id,:)
311 land_pelist(:) = ensemble_pelist_land(ensemble_id,:)
312 ice_pelist(:) = ensemble_pelist_ice(ensemble_id,:)
363 write(pelist_name,
'(a,i2.2)')
'atm_ens',n
365 write(pelist_name,
'(a,i2.2)')
'ocn_ens',n
367 write(pelist_name,
'(a,i2.2)')
'lnd_ens',n
369 write(pelist_name,
'(a,i2.2)')
'ice_ens',n
373 write(pelist_name,
'(a,i2.2)')
'atm_ens',ensemble_id
375 write(pelist_name,
'(a,i2.2)')
'ocn_ens',ensemble_id
377 write(pelist_name,
'(a,i2.2)')
'lnd_ens',ensemble_id
379 write(pelist_name,
'(a,i2.2)')
'ice_ens',ensemble_id
383 ocean_npes_pm = ocean_npes
384 atmos_npes_pm = atmos_npes
385 land_npes_pm = land_npes
386 ice_npes_pm = ice_npes
389 allocate(ensemble_pelist_ocean_filter(ensemble_size * ocean_npes_pm))
390 allocate(ensemble_pelist_atmos_filter(ensemble_size * atmos_npes_pm))
391 allocate(ensemble_pelist_land_filter(ensemble_size * land_npes_pm))
392 allocate(ensemble_pelist_ice_filter(ensemble_size * ice_npes_pm))
395 i=(n-1)*ocean_npes_pm + m
396 ensemble_pelist_ocean_filter(i) = ensemble_pelist_ocean(n,m)
399 i=(n-1)*atmos_npes_pm + m
400 ensemble_pelist_atmos_filter(i) = ensemble_pelist_atmos(n,m)
403 i=(n-1)*land_npes_pm + m
404 ensemble_pelist_land_filter(i) = ensemble_pelist_land(n,m)
407 i=(n-1)*ice_npes_pm + m
408 ensemble_pelist_ice_filter(i) = ensemble_pelist_ice(n,m)
412 write(pelist_name,
'(a)')
'ocn_filter'
415 write(pelist_name,
'(a)')
'atm_filter'
418 write(pelist_name,
'(a)')
'lnd_filter'
421 write(pelist_name,
'(a)')
'ice_filter'
429 if (ensemble_size > 1)
then
431 write( text,
'(a,i2.2)' )
'ens_', global_ens
433 call fms2_io_set_filename_appendix(trim(text))
439 end module ensemble_manager_mod
integer function, public get_ensemble_id()
Getter function for ensemble_id.
integer function, dimension(6), public get_ensemble_size()
Returns ensemble size integer array.
integer starting_ensemble_id
Starting index for ensemble numbering in I/O filenames.
subroutine, public ensemble_pelist_setup(concurrent, atmos_npes, ocean_npes, land_npes, ice_npes, Atm_pelist, Ocean_pelist, Land_pelist, Ice_pelist)
Sets up pe list for an ensemble.
subroutine, public ensemble_manager_init()
Initializes ensemble_manager_mod.
subroutine, public get_ensemble_pelist(pelist, name)
Gets pe list for current ensemble or a given ensemble component.
subroutine, public get_ensemble_filter_pelist(pelist, name)
Gets filter pelist for a given ensemble component.
integer function, public check_nml_error(IOSTAT, NML_NAME)
Checks the iostat argument that is returned after reading a namelist and determines if the error code...
integer function stdout()
This function returns the current standard fortran unit numbers for output.
subroutine mpp_declare_pelist(pelist, name, commID)
Declare a pelist.
integer function stdlog()
This function returns the current standard fortran unit numbers for log messages. Log messages,...
integer function mpp_npes()
Returns processor count for current pelist.
integer function mpp_pe()
Returns processor ID.