Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial attempt of setting default constituent value. #226

Merged
merged 14 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Externals_CAM.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
local_path = ccpp_framework
protocol = git
repo_url = https://github.com/peverwhee/ccpp-framework
tag = CPF_0.2.043
tag = CPF_0.2.045
required = True

[cosp2]
Expand Down
41 changes: 38 additions & 3 deletions src/data/write_init_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,10 +819,12 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports,
["physics_data", ["read_field", "find_input_name_idx",
"no_exist_idx", "init_mark_idx",
"prot_no_init_idx", "const_idx"]],
["cam_ccpp_cap", ["ccpp_physics_suite_variables", "cam_constituents_array"]],
["cam_ccpp_cap", ["ccpp_physics_suite_variables", "cam_constituents_array", "cam_model_const_properties"]],
["ccpp_kinds", ["kind_phys"]],
[phys_check_fname_str, ["phys_var_stdnames",
"input_var_names", "std_name_len"]]]
"input_var_names", "std_name_len"]],
["ccpp_constituent_prop_mod", ["ccpp_constituent_prop_ptr_t"]],
["cam_logfile", ["iulog"]]]

# Add in host model data use statements
use_stmts.extend(host_imports)
Expand Down Expand Up @@ -860,6 +862,14 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports,
outfile.write("character(len=2) :: sep2 !String separator used to print err messages", 2)
outfile.write("character(len=2) :: sep3 !String separator used to print err messages", 2)
outfile.write("real(kind=kind_phys), pointer :: field_data_ptr(:,:,:)", 2)
outfile.write("logical :: var_found !Bool to determine if consituent found in data files", 2)
outfile.blank_line()
outfile.comment("Fields needed for getting default data value for constituents", 2)
outfile.write("type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:)", 2)
outfile.write("real(kind=kind_phys) :: constituent_default_value", 2)
outfile.write("integer :: constituent_errflg", 2)
outfile.write("character(len=512) :: constituent_errmsg", 2)
outfile.write("logical :: constituent_has_default", 2)
outfile.blank_line()
outfile.comment("Logical to default optional argument to False:", 2)
outfile.write("logical :: use_init_variables", 2)
Expand Down Expand Up @@ -949,8 +959,33 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports,
outfile.blank_line()
outfile.comment("If an index was found in the constituent hash table, then read in the data to that index of the constituent array", 6)
outfile.blank_line()
outfile.write("var_found = .false.", 6)
outfile.write("field_data_ptr => cam_constituents_array()", 6)
outfile.write("call read_field(file, ccpp_required_data(req_idx), [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false.)", 6)
outfile.write("call read_field(file, ccpp_required_data(req_idx), [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found)", 6)
outfile.write("if(.not. var_found) then", 6)
outfile.write("const_props => cam_model_const_properties()", 7)
outfile.write("constituent_has_default = .false.", 7)
outfile.write("call const_props(constituent_idx)%has_default(constituent_has_default, constituent_errflg, constituent_errmsg)", 7)
outfile.write("if (constituent_errflg /= 0) then", 7)
outfile.write("call endrun(constituent_errmsg, file=__FILE__, line=__LINE__)", 8)
outfile.write("end if", 7)
outfile.write("if (constituent_has_default) then", 7)
outfile.write("call const_props(constituent_idx)%default_value(constituent_default_value, constituent_errflg, constituent_errmsg)", 8)
nusbaume marked this conversation as resolved.
Show resolved Hide resolved
outfile.write("if (constituent_errflg /= 0) then", 8)
outfile.write("call endrun(constituent_errmsg, file=__FILE__, line=__LINE__)", 9)
outfile.write("end if", 8)
outfile.write("field_data_ptr(:,:,constituent_idx) = constituent_default_value", 8)
outfile.write("if (masterproc) then", 8)
outfile.write("write(iulog,*) 'Consitituent ', ccpp_required_data(req_idx), ' initialized to default value: ', constituent_default_value", 9)
outfile.write("end if", 8)
outfile.write("else", 7)
outfile.write("field_data_ptr(:,:,constituent_idx) = 0._kind_phys", 8)
outfile.write("if (masterproc) then", 8)
outfile.write("write(iulog,*) 'Constituent ', ccpp_required_data(req_idx), ' default value not configured. Setting to 0.'", 9)
outfile.write("end if", 8)
outfile.write("end if", 7)
outfile.write("end if", 6)
outfile.blank_line()

# start default case steps:
outfile.write("case default", 5)
Expand Down
6 changes: 3 additions & 3 deletions src/dynamics/se/dyn_comp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1843,9 +1843,9 @@ subroutine read_inidat(dyn_in)
call mark_as_initialized("reciprocal_of_pressure_thickness")
call mark_as_initialized("inverse_exner_function_wrt_surface_pressure")
call mark_as_initialized("lagrangian_tendency_of_air_pressure")
call mark_as_initialized("total_tendency_of_air_temperature")
call mark_as_initialized("total_tendency_of_x_wind")
call mark_as_initialized("total_tendency_of_y_wind")
call mark_as_initialized("tendency_of_air_temperature_due_to_model_physics")
call mark_as_initialized("tendency_of_x_wind_due_to_model_physics")
call mark_as_initialized("tendency_of_y_wind_due_to_model_physics")
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved

end subroutine read_inidat

Expand Down
102 changes: 73 additions & 29 deletions src/physics/utils/physics_data.F90
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function arr2str(name_array)
end function arr2str


subroutine read_field_2d(file, std_name, var_names, timestep, buffer, mark_as_read)
subroutine read_field_2d(file, std_name, var_names, timestep, buffer, mark_as_read, error_on_not_found, var_found)
use shr_assert_mod, only: shr_assert_in_domain
use shr_sys_mod, only: shr_sys_flush
use pio, only: file_desc_t, var_desc_t
Expand All @@ -155,10 +155,13 @@ subroutine read_field_2d(file, std_name, var_names, timestep, buffer, mark_as_re
character(len=*), intent(in) :: var_names(:) ! var name on file
integer, intent(in) :: timestep
real(kind_phys), intent(inout) :: buffer(:)
logical, optional, intent(in) :: mark_as_read
logical, optional, intent(in) :: mark_as_read ! Mark field as read if found
logical, optional, intent(in) :: error_on_not_found ! Flag to error and exit if not found
logical, optional, intent(out) :: var_found ! Flag to mark variable was found
! Local variables
logical :: mark_as_read_local
logical :: var_found
logical :: error_on_not_found_local
logical :: var_found_local
character(len=std_name_len) :: found_name
type(var_desc_t) :: vardesc
character(len=*), parameter :: subname = 'read_field_2d: '
Expand All @@ -169,35 +172,54 @@ subroutine read_field_2d(file, std_name, var_names, timestep, buffer, mark_as_re
mark_as_read_local = .true.
end if

call cam_pio_find_var(file, var_names, found_name, vardesc, var_found)
if (.not. var_found) then
call cam_pio_find_var(file, [std_name], found_name, vardesc, var_found)
if (present(error_on_not_found)) then
error_on_not_found_local = error_on_not_found
else
error_on_not_found_local = .true.
end if

if (var_found) then
var_found_local = .false.
call cam_pio_find_var(file, var_names, found_name, vardesc, var_found_local)
if (.not. var_found_local) then
call cam_pio_find_var(file, [std_name], found_name, vardesc, var_found_local)
end if

if (var_found_local) then
if (masterproc) then
write(iulog, *) 'Reading input field, ', trim(found_name)
call shr_sys_flush(iulog)
end if
call cam_read_field(found_name, file, buffer, var_found, &
call cam_read_field(found_name, file, buffer, var_found_local, &
timelevel=timestep)

if (mark_as_read_local) then
call mark_as_read_from_file(std_name)
end if

if (var_found_local) then
call shr_assert_in_domain(buffer, is_nan=.false., &
varname=trim(found_name), &
msg=subname//'NaN found in '//trim(found_name))
else
call endrun(subname//'Unable to properly check the found variable "',trim(found_name),'" in the IC file. ' &
'Please double-check if the variable exists in the file, ' &
'and that the file is not corrupted or damaged.')
end if
else if (.not. error_on_not_found_local) then
if (masterproc) then
write(iulog, *) trim(std_name), ' not found, also looked for: ', trim(arr2str(var_names))
call shr_sys_flush(iulog)
end if
else
call endrun(subname//'No variable found in '//arr2str(var_names))
end if
if (var_found) then
call shr_assert_in_domain(buffer, is_nan=.false., &
varname=trim(found_name), &
msg=subname//'NaN found in '//trim(found_name))
else
call endrun(subname//'Mismatch variable found in '//arr2str(var_names))
end if
if (present(var_found)) then
var_found = var_found_local
end if
end subroutine read_field_2d

subroutine read_field_3d(file, std_name, var_names, vcoord_name, &
timestep, buffer, mark_as_read)
timestep, buffer, mark_as_read, error_on_not_found, var_found)
cacraigucar marked this conversation as resolved.
Show resolved Hide resolved
use shr_assert_mod, only: shr_assert_in_domain
use shr_sys_mod, only: shr_sys_flush
use pio, only: file_desc_t, var_desc_t
Expand All @@ -219,10 +241,13 @@ subroutine read_field_3d(file, std_name, var_names, vcoord_name, &
character(len=*), intent(in) :: vcoord_name
integer, intent(in) :: timestep
real(kind_phys), intent(inout) :: buffer(:,:)
logical, optional, intent(in) :: mark_as_read
logical, optional, intent(in) :: mark_as_read ! Mark field as read if found
logical, optional, intent(in) :: error_on_not_found ! Flag to error and exit if not found
logical, optional, intent(out) :: var_found ! Flag to mark variable was found
! Local variables
logical :: mark_as_read_local
logical :: var_found
logical :: error_on_not_found_local
logical :: var_found_local
integer :: num_levs
character(len=std_name_len) :: found_name
type(var_desc_t) :: vardesc
Expand All @@ -234,12 +259,20 @@ subroutine read_field_3d(file, std_name, var_names, vcoord_name, &
mark_as_read_local = .true.
end if

call cam_pio_find_var(file, var_names, found_name, vardesc, var_found)
if (present(error_on_not_found)) then
error_on_not_found_local = error_on_not_found
else
error_on_not_found_local = .true.
end if

if (.not. var_found) then
call cam_pio_find_var(file, [std_name], found_name, vardesc, var_found)
var_found_local = .false.
call cam_pio_find_var(file, var_names, found_name, vardesc, var_found_local)

if (.not. var_found_local) then
call cam_pio_find_var(file, [std_name], found_name, vardesc, var_found_local)
end if
if (var_found) then

if (var_found_local) then
if (trim(vcoord_name) == 'lev') then
num_levs = pver
else if (trim(vcoord_name) == 'ilev') then
Expand All @@ -251,21 +284,32 @@ subroutine read_field_3d(file, std_name, var_names, vcoord_name, &
write(iulog, *) 'Reading input field, ', trim(found_name)
call shr_sys_flush(iulog)
end if
call cam_read_field(found_name, file, buffer, var_found, &
call cam_read_field(found_name, file, buffer, var_found_local, &
timelevel=timestep, dim3name=trim(vcoord_name), &
dim3_bnds=(/1, num_levs/))

if (mark_as_read_local) then
call mark_as_read_from_file(std_name)
end if
if (var_found_local) then
call shr_assert_in_domain(buffer, is_nan=.false., &
varname=trim(found_name), &
msg=subname//'NaN found in '//trim(found_name))
else
call endrun(subname//'Unable to properly check the found variable "',trim(found_name),'" in the IC file. ' &
'Please double-check if the variable exists in the file, ' &
'and that the file is not corrupted or damaged.')
end if
else if (.not. error_on_not_found_local) then
if (masterproc) then
write(iulog, *) trim(std_name), ' not found, also looked for: ', trim(arr2str(var_names))
call shr_sys_flush(iulog)
end if
else
call endrun(subname//'No variable found in '//arr2str(var_names))
end if
if (var_found) then
call shr_assert_in_domain(buffer, is_nan=.false., &
varname=trim(found_name), &
msg=subname//'NaN found in '//trim(found_name))
else
call endrun(subname//'Mismatch variable found in '//found_name)
if (present(var_found)) then
var_found = var_found_local
end if
end subroutine read_field_3d

Expand Down
63 changes: 53 additions & 10 deletions test/unit/sample_files/write_init_files/physics_inputs_4D.F90
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,18 @@ module physics_inputs_4D
CONTAINS

subroutine physics_read_data(file, suite_names, timestep, read_initialized_variables)
use pio, only: file_desc_t
use cam_abortutils, only: endrun
use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX
use physics_data, only: read_field, find_input_name_idx, no_exist_idx
use physics_data, only: init_mark_idx, prot_no_init_idx, const_idx
use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array
use ccpp_kinds, only: kind_phys
use phys_vars_init_check_4D, only: phys_var_stdnames, input_var_names, std_name_len
use physics_types_4D, only: slp, theta
use pio, only: file_desc_t
use cam_abortutils, only: endrun
use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX
use physics_data, only: read_field, find_input_name_idx, no_exist_idx
use physics_data, only: init_mark_idx, prot_no_init_idx, const_idx
use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array
use cam_ccpp_cap, only: cam_model_const_properties
use ccpp_kinds, only: kind_phys
use phys_vars_init_check_4D, only: phys_var_stdnames, input_var_names, std_name_len
use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t
use cam_logfile, only: iulog
use physics_types_4D, only: slp, theta

! Dummy arguments
type(file_desc_t), intent(inout) :: file
Expand All @@ -64,6 +67,15 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia
character(len=2) :: sep2 !String separator used to print err messages
character(len=2) :: sep3 !String separator used to print err messages
real(kind=kind_phys), pointer :: field_data_ptr(:,:,:)
logical :: var_found !Bool to determine if consituent found in
! data files

! Fields needed for getting default data value for constituents
type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:)
real(kind=kind_phys) :: constituent_default_value
integer :: constituent_errflg
character(len=512) :: constituent_errmsg
logical :: constituent_has_default

! Logical to default optional argument to False:
logical :: use_init_variables
Expand Down Expand Up @@ -130,10 +142,41 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia
! If an index was found in the constituent hash table, then read in the data
! to that index of the constituent array

var_found = .false.
field_data_ptr => cam_constituents_array()
call read_field(file, ccpp_required_data(req_idx), &
[ccpp_required_data(req_idx)], 'lev', timestep, &
field_data_ptr(:,:,constituent_idx), mark_as_read=.false.)
field_data_ptr(:,:,constituent_idx), mark_as_read=.false., &
error_on_not_found=.false., var_found=var_found)
if(.not. var_found) then
const_props => cam_model_const_properties()
constituent_has_default = .false.
call const_props(constituent_idx)%has_default(constituent_has_default, &
constituent_errflg, constituent_errmsg)
if (constituent_errflg /= 0) then
call endrun(constituent_errmsg, file=__FILE__, line=__LINE__)
end if
if (constituent_has_default) then
call &
const_props(constituent_idx)%default_value(constituent_default_value, constituent_errflg,&
constituent_errmsg)
nusbaume marked this conversation as resolved.
Show resolved Hide resolved
if (constituent_errflg /= 0) then
call endrun(constituent_errmsg, file=__FILE__, line=__LINE__)
end if
field_data_ptr(:,:,constituent_idx) = constituent_default_value
if (masterproc) then
write(iulog,*) 'Consitituent ', ccpp_required_data(req_idx), &
' initialized to default value: ', constituent_default_value
end if
else
field_data_ptr(:,:,constituent_idx) = 0._kind_phys
if (masterproc) then
write(iulog,*) 'Constituent ', ccpp_required_data(req_idx), &
' default value not configured. Setting to 0.'
end if
end if
end if

case default

! Read variable from IC file:
Expand Down
Loading