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.
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.
Declare a pelist. The two flavors of this subroutine differ in the type of their comm/commID argument...