Skip to content

Commit 9f2e0f7

Browse files
committed
New functionality that runs all scheme _init routines as part of ccpp_physics_init after an optional/additional init routine XXX specified as <init>XXX</init> in the SDF. For XXX, only the XXX_run function is used. Similarly, all scheme _finalize routines are run as part of ccpp_physics_finalize, before an optional/additional finalize routine YYY specified as <finalize>YYY</finalize> in the SDF. For YYY, only the YYY_run function is used.
1 parent dea4995 commit 9f2e0f7

7 files changed

+393
-127
lines changed

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ set(SOURCES_F90
2626
ccpp_fields.F90
2727
ccpp_memory.F90
2828
ccpp_strings.F90
29+
ccpp_scheme.F90
2930
ccpp_suite.F90
3031
ccpp_types.F90
3132
ccpp_xml.F90

src/ccpp_dl.F90

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ module ccpp_dl
2020
interface
2121
integer(c_int32_t) &
2222
function ccpp_dl_open &
23-
(name, library, version, shdl, lhdl) &
23+
(name, library, version, fhdl, lhdl) &
2424
bind(c, name='ccpp_dl_open')
2525
import :: c_char, c_int32_t, c_ptr
2626
character(kind=c_char), dimension(*) :: name
2727
character(kind=c_char), dimension(*) :: library
2828
character(kind=c_char), dimension(*) :: version
29-
type(c_ptr) :: shdl
29+
type(c_ptr) :: fhdl
3030
type(c_ptr) :: lhdl
3131
end function ccpp_dl_open
3232

src/ccpp_dl.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ static const char suffix[] = ".so";
5151
* @param[in] scheme The scheme name to call.
5252
* @param[in] lib The library continaing the physics scheme.
5353
* @param[in] ver The library version number.
54-
* @param[out] shdl The scheme function pointer handle.
54+
* @param[out] fhdl The scheme function pointer handle.
5555
* @param[out] lhdl The library handle.
5656
* @retval 0 If it was sucessful
5757
* @retval 1 If there was an error
5858
**/
5959
int
6060
ccpp_dl_open(const char *scheme, const char *lib, const char *ver,
61-
void **shdl, void **lhdl)
61+
void **fhdl, void **lhdl)
6262
{
6363
int i = 0;
6464
int n = 0;
@@ -115,7 +115,7 @@ ccpp_dl_open(const char *scheme, const char *lib, const char *ver,
115115
}
116116

117117
dlerror();
118-
*(void **)shdl = dlsym(*lhdl, scheme_cap);
118+
*(void **)fhdl = dlsym(*lhdl, scheme_cap);
119119
if ((error = dlerror()) != NULL) {
120120
warnx("%s", error);
121121
return(EXIT_FAILURE);

src/ccpp_fcall.F90

+94-37
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ module ccpp_fcall
1010
only: c_int32_t, c_char, c_ptr, c_loc, c_funptr
1111
use :: ccpp_types, &
1212
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
1415
use :: ccpp_errors, &
1516
only: ccpp_error, ccpp_debug
1617
use :: ccpp_strings, &
@@ -46,8 +47,13 @@ subroutine ccpp_physics_init(cdata, ierr)
4647
ierr = 0
4748
call ccpp_debug('Called ccpp_physics_init')
4849

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)
5157

5258
end subroutine ccpp_physics_init
5359

@@ -99,24 +105,24 @@ subroutine ccpp_physics_run(cdata, group_name, subcycle_count, scheme_name, ierr
99105

100106
if (present(group_name)) then
101107
! 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)
103109
if (ierr/=0) return
104110
if (present(subcycle_count)) then
105111
! 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)
107113
if (ierr/=0) return
108-
call ccpp_run_subcycle(subcycle, cdata, ierr)
114+
call ccpp_run_subcycle(subcycle, cdata, ierr=ierr)
109115
else
110-
call ccpp_run_group(group, cdata, ierr)
116+
call ccpp_run_group(group, cdata, ierr=ierr)
111117
end if
112118
else if (present(scheme_name)) then
113119
! 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)
115121
if (ierr/=0) return
116-
call ccpp_run_scheme(scheme, cdata, ierr)
122+
call ccpp_run_scheme(scheme, cdata, ierr=ierr)
117123
else
118124
! 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)
120126
end if
121127

122128
end subroutine ccpp_physics_run
@@ -138,8 +144,13 @@ subroutine ccpp_physics_finalize(cdata, ierr)
138144
ierr = 0
139145
call ccpp_debug('Called ccpp_physics_finalize')
140146

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
143154

144155
end subroutine ccpp_physics_finalize
145156

@@ -153,13 +164,15 @@ end subroutine ccpp_physics_finalize
153164
!!
154165
!! @param[in ] suite The suite to run
155166
!! @param[in,out] cdata The CCPP data of type ccpp_t
167+
!! @param[in ] stage The stage for which to run the suite
156168
!! @param[ out] ierr Integer error flag
157169
!
158-
subroutine ccpp_run_suite(suite, cdata, ierr)
170+
subroutine ccpp_run_suite(suite, cdata, stage, ierr)
159171

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
163176

164177
integer :: i
165178

@@ -168,7 +181,7 @@ subroutine ccpp_run_suite(suite, cdata, ierr)
168181
call ccpp_debug('Called ccpp_run_suite')
169182

170183
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)
172185
if (ierr /= 0) then
173186
return
174187
end if
@@ -216,13 +229,15 @@ end function ccpp_find_group
216229
!!
217230
!! @param[in ] group The group to run
218231
!! @param[in,out] cdata The CCPP data of type ccpp_t
232+
!! @param[in ] stage The stage for which to run the group
219233
!! @param[ out] ierr Integer error flag
220234
!
221-
subroutine ccpp_run_group(group, cdata, ierr)
235+
subroutine ccpp_run_group(group, cdata, stage, ierr)
222236

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
226241

227242
integer :: i
228243

@@ -231,7 +246,7 @@ subroutine ccpp_run_group(group, cdata, ierr)
231246
call ccpp_debug('Called ccpp_run_group')
232247

233248
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)
235250
if (ierr /= 0) then
236251
return
237252
end if
@@ -277,13 +292,15 @@ end function ccpp_find_subcycle
277292
!!
278293
!! @param[in ] subcycle The subcycle to run
279294
!! @param[in,out] cdata The CCPP data of type ccpp_t
295+
!! @param[in ] stage The stage for which to run the subcycle
280296
!! @param[ out] ierr Integer error flag
281297
!
282-
subroutine ccpp_run_subcycle(subcycle, cdata, ierr)
298+
subroutine ccpp_run_subcycle(subcycle, cdata, stage, ierr)
283299

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
287304

288305
integer :: i
289306
integer :: j
@@ -294,7 +311,7 @@ subroutine ccpp_run_subcycle(subcycle, cdata, ierr)
294311

295312
do i=1,subcycle%loop
296313
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)
298315
if (ierr /= 0) then
299316
return
300317
end if
@@ -348,24 +365,64 @@ end function ccpp_find_scheme
348365
!!
349366
!! @param[in ] scheme The scheme to run
350367
!! @param[in,out] cdata The CCPP data of type ccpp_t
368+
!! @param[in ] stage The stage for which to run the scheme
351369
!! @param[ out] ierr Integer error flag
352370
!
353-
subroutine ccpp_run_scheme(scheme, cdata, ierr)
371+
subroutine ccpp_run_scheme(scheme, cdata, stage, ierr)
354372

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
358377

359-
ierr = 0
378+
character(:), allocatable :: stage_local
379+
character(:), allocatable :: function_name
380+
integer :: l
360381

361-
call ccpp_debug('Called ccpp_run_scheme for "' // trim(scheme%name) // '"')
382+
ierr = 0
362383

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)
367388
end if
368389

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+
369426
end subroutine ccpp_run_scheme
370427

371428
#if 0

0 commit comments

Comments
 (0)