@@ -10,7 +10,8 @@ module ccpp_fcall
10
10
only: c_int32_t, c_char, c_ptr, c_loc, c_funptr
11
11
use :: ccpp_types, &
12
12
only: ccpp_t, ccpp_suite_t, ccpp_group_t, &
13
- ccpp_subcycle_t, ccpp_scheme_t
13
+ ccpp_subcycle_t, ccpp_scheme_t, &
14
+ CCPP_STAGES, CCPP_DEFAULT_STAGE
14
15
use :: ccpp_errors, &
15
16
only: ccpp_error, ccpp_debug
16
17
use :: ccpp_strings, &
@@ -46,8 +47,13 @@ subroutine ccpp_physics_init(cdata, ierr)
46
47
ierr = 0
47
48
call ccpp_debug(' Called ccpp_physics_init' )
48
49
49
- scheme = cdata% suite% init
50
- call ccpp_run_scheme(scheme, cdata, ierr)
50
+ ! The extra init scheme uses the 'run' stage for the init call
51
+ if (allocated (cdata% suite% init% name)) then
52
+ scheme = cdata% suite% init
53
+ call ccpp_run_scheme(scheme, cdata, stage= ' run' , ierr= ierr)
54
+ end if
55
+
56
+ call ccpp_run_suite(cdata% suite, cdata, stage= ' init' , ierr= ierr)
51
57
52
58
end subroutine ccpp_physics_init
53
59
@@ -99,24 +105,24 @@ subroutine ccpp_physics_run(cdata, group_name, subcycle_count, scheme_name, ierr
99
105
100
106
if (present (group_name)) then
101
107
! Find the group to run from the suite
102
- group = > ccpp_find_group(suite, group_name, ierr)
108
+ group = > ccpp_find_group(suite, group_name, ierr= ierr )
103
109
if (ierr/= 0 ) return
104
110
if (present (subcycle_count)) then
105
111
! Find the subcycle to run in the current group
106
- subcycle = > ccpp_find_subcycle(group, subcycle_count, ierr)
112
+ subcycle = > ccpp_find_subcycle(group, subcycle_count, ierr= ierr )
107
113
if (ierr/= 0 ) return
108
- call ccpp_run_subcycle(subcycle, cdata, ierr)
114
+ call ccpp_run_subcycle(subcycle, cdata, ierr= ierr )
109
115
else
110
- call ccpp_run_group(group, cdata, ierr)
116
+ call ccpp_run_group(group, cdata, ierr= ierr )
111
117
end if
112
118
else if (present (scheme_name)) then
113
119
! Find the scheme to run from the suite
114
- scheme = > ccpp_find_scheme(suite, scheme_name, ierr)
120
+ scheme = > ccpp_find_scheme(suite, scheme_name, ierr= ierr )
115
121
if (ierr/= 0 ) return
116
- call ccpp_run_scheme(scheme, cdata, ierr)
122
+ call ccpp_run_scheme(scheme, cdata, ierr= ierr )
117
123
else
118
124
! If none of the optional arguments is present, run the entire suite
119
- call ccpp_run_suite(suite, cdata, ierr)
125
+ call ccpp_run_suite(suite, cdata, ierr= ierr )
120
126
end if
121
127
122
128
end subroutine ccpp_physics_run
@@ -138,8 +144,13 @@ subroutine ccpp_physics_finalize(cdata, ierr)
138
144
ierr = 0
139
145
call ccpp_debug(' Called ccpp_physics_finalize' )
140
146
141
- scheme = cdata% suite% finalize
142
- call ccpp_run_scheme(scheme, cdata, ierr)
147
+ call ccpp_run_suite(cdata% suite, cdata, stage= ' finalize' , ierr= ierr)
148
+
149
+ ! The extra finalize scheme uses the 'run' stage for the finalize call
150
+ if (allocated (cdata% suite% finalize% name)) then
151
+ scheme = cdata% suite% finalize
152
+ call ccpp_run_scheme(scheme, cdata, stage= ' run' , ierr= ierr)
153
+ end if
143
154
144
155
end subroutine ccpp_physics_finalize
145
156
@@ -153,13 +164,15 @@ end subroutine ccpp_physics_finalize
153
164
! !
154
165
! ! @param[in ] suite The suite to run
155
166
! ! @param[in,out] cdata The CCPP data of type ccpp_t
167
+ ! ! @param[in ] stage The stage for which to run the suite
156
168
! ! @param[ out] ierr Integer error flag
157
169
!
158
- subroutine ccpp_run_suite (suite , cdata , ierr )
170
+ subroutine ccpp_run_suite (suite , cdata , stage , ierr )
159
171
160
- type (ccpp_suite_t), intent (inout ) :: suite
161
- type (ccpp_t), target , intent (inout ) :: cdata
162
- integer , intent ( out ) :: ierr
172
+ type (ccpp_suite_t), intent (inout ) :: suite
173
+ type (ccpp_t), target , intent (inout ) :: cdata
174
+ character (len=* ), intent (in ), optional :: stage
175
+ integer , intent ( out ) :: ierr
163
176
164
177
integer :: i
165
178
@@ -168,7 +181,7 @@ subroutine ccpp_run_suite(suite, cdata, ierr)
168
181
call ccpp_debug(' Called ccpp_run_suite' )
169
182
170
183
do i= 1 ,suite% groups_max
171
- call ccpp_run_group(suite% groups(i), cdata, ierr)
184
+ call ccpp_run_group(suite% groups(i), cdata, stage = stage, ierr = ierr)
172
185
if (ierr /= 0 ) then
173
186
return
174
187
end if
@@ -216,13 +229,15 @@ end function ccpp_find_group
216
229
! !
217
230
! ! @param[in ] group The group to run
218
231
! ! @param[in,out] cdata The CCPP data of type ccpp_t
232
+ ! ! @param[in ] stage The stage for which to run the group
219
233
! ! @param[ out] ierr Integer error flag
220
234
!
221
- subroutine ccpp_run_group (group , cdata , ierr )
235
+ subroutine ccpp_run_group (group , cdata , stage , ierr )
222
236
223
- type (ccpp_group_t), intent (inout ) :: group
224
- type (ccpp_t), target , intent (inout ) :: cdata
225
- integer , intent ( out ) :: ierr
237
+ type (ccpp_group_t), intent (inout ) :: group
238
+ type (ccpp_t), target , intent (inout ) :: cdata
239
+ character (len=* ), intent (in ), optional :: stage
240
+ integer , intent ( out ) :: ierr
226
241
227
242
integer :: i
228
243
@@ -231,7 +246,7 @@ subroutine ccpp_run_group(group, cdata, ierr)
231
246
call ccpp_debug(' Called ccpp_run_group' )
232
247
233
248
do i= 1 ,group% subcycles_max
234
- call ccpp_run_subcycle(group% subcycles(i), cdata, ierr)
249
+ call ccpp_run_subcycle(group% subcycles(i), cdata, stage = stage, ierr = ierr)
235
250
if (ierr /= 0 ) then
236
251
return
237
252
end if
@@ -277,13 +292,15 @@ end function ccpp_find_subcycle
277
292
! !
278
293
! ! @param[in ] subcycle The subcycle to run
279
294
! ! @param[in,out] cdata The CCPP data of type ccpp_t
295
+ ! ! @param[in ] stage The stage for which to run the subcycle
280
296
! ! @param[ out] ierr Integer error flag
281
297
!
282
- subroutine ccpp_run_subcycle (subcycle , cdata , ierr )
298
+ subroutine ccpp_run_subcycle (subcycle , cdata , stage , ierr )
283
299
284
- type (ccpp_subcycle_t), intent (inout ) :: subcycle
285
- type (ccpp_t), target , intent (inout ) :: cdata
286
- integer , intent ( out ) :: ierr
300
+ type (ccpp_subcycle_t), intent (inout ) :: subcycle
301
+ type (ccpp_t), target , intent (inout ) :: cdata
302
+ character (len=* ), intent (in ), optional :: stage
303
+ integer , intent ( out ) :: ierr
287
304
288
305
integer :: i
289
306
integer :: j
@@ -294,7 +311,7 @@ subroutine ccpp_run_subcycle(subcycle, cdata, ierr)
294
311
295
312
do i= 1 ,subcycle% loop
296
313
do j= 1 ,subcycle% schemes_max
297
- call ccpp_run_scheme(subcycle% schemes(j), cdata, ierr)
314
+ call ccpp_run_scheme(subcycle% schemes(j), cdata, stage = stage, ierr = ierr)
298
315
if (ierr /= 0 ) then
299
316
return
300
317
end if
@@ -348,24 +365,64 @@ end function ccpp_find_scheme
348
365
! !
349
366
! ! @param[in ] scheme The scheme to run
350
367
! ! @param[in,out] cdata The CCPP data of type ccpp_t
368
+ ! ! @param[in ] stage The stage for which to run the scheme
351
369
! ! @param[ out] ierr Integer error flag
352
370
!
353
- subroutine ccpp_run_scheme (scheme , cdata , ierr )
371
+ subroutine ccpp_run_scheme (scheme , cdata , stage , ierr )
354
372
355
- type (ccpp_scheme_t), intent (in ) :: scheme
356
- type (ccpp_t), target , intent (inout ) :: cdata
357
- integer , intent ( out ) :: ierr
373
+ type (ccpp_scheme_t), intent (in ) :: scheme
374
+ type (ccpp_t), target , intent (inout ) :: cdata
375
+ character (len=* ), intent (in ), optional :: stage
376
+ integer , intent ( out ) :: ierr
358
377
359
- ierr = 0
378
+ character (:), allocatable :: stage_local
379
+ character (:), allocatable :: function_name
380
+ integer :: l
360
381
361
- call ccpp_debug( ' Called ccpp_run_scheme for " ' // trim (scheme % name) // ' " ' )
382
+ ierr = 0
362
383
363
- ierr = ccpp_dl_call(scheme % scheme_hdl, c_loc(cdata))
364
- if (ierr /= 0 ) then
365
- call ccpp_error( ' A problem occured calling ' // &
366
- trim (scheme % name) // ' scheme ' )
384
+ if ( present (stage)) then
385
+ stage_local = trim (stage)
386
+ else
387
+ stage_local = trim (CCPP_DEFAULT_STAGE )
367
388
end if
368
389
390
+ call ccpp_debug(' Called ccpp_run_scheme for ' // trim (scheme% name) &
391
+ // ' in stage ' // trim (stage_local))
392
+
393
+ function_name = trim (scheme% get_function_name(stage_local))
394
+
395
+ do l= 1 ,scheme% functions_max
396
+ associate (f= >scheme% functions(l))
397
+ if (trim (function_name) == trim (f% name)) then
398
+ ierr = ccpp_dl_call(f% function_hdl, c_loc(cdata))
399
+ if (ierr /= 0 ) then
400
+ call ccpp_error(' A problem occured calling ' // trim (f% name) &
401
+ // ' of scheme ' // trim (scheme% name) &
402
+ // ' in stage ' // trim (stage_local))
403
+ end if
404
+ ! Return after calling the scheme, with or without error
405
+ return
406
+ end if
407
+ end associate
408
+ end do
409
+
410
+ ! If we reach this point, the required function was not found
411
+ ierr = 1
412
+ do l= 1 ,size (CCPP_STAGES)
413
+ if (trim (stage_local) == trim (CCPP_STAGES(l))) then
414
+ ! Stage is valid --> problem with the scheme
415
+ call ccpp_error(' Function ' // trim (function_name) &
416
+ // ' of scheme ' // trim (scheme% name) &
417
+ // ' for stage ' // trim (stage_local) &
418
+ // ' not found in suite' )
419
+ return
420
+ end if
421
+ end do
422
+ ! Stage is invalid
423
+ call ccpp_error(' Invalid stage ' // trim (stage_local) &
424
+ // ' requested in ccpp_run_scheme' )
425
+
369
426
end subroutine ccpp_run_scheme
370
427
371
428
#if 0
0 commit comments