From 3c63ad17d6baec97ff8177b791716f070b80c322 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Thu, 19 Sep 2024 18:55:36 -0600 Subject: [PATCH 01/11] read in all constituents from file; not just build-time ones --- cime_config/cam_autogen.py | 13 +- cime_config/cam_build_cache.py | 16 +- cime_config/cam_config.py | 4 +- src/data/generate_registry_data.py | 29 ++- src/data/write_init_files.py | 229 ++++++++++++------ .../update_reg_build_cache.xml | 2 + .../phys_vars_init_check_cnst.F90 | 10 +- .../write_init_files/physics_inputs_4D.F90 | 175 +++++++------ .../write_init_files/physics_inputs_bvd.F90 | 149 +++++++----- .../write_init_files/physics_inputs_cnst.F90 | 149 +++++++----- .../write_init_files/physics_inputs_ddt.F90 | 175 +++++++------ .../write_init_files/physics_inputs_ddt2.F90 | 149 +++++++----- .../physics_inputs_ddt_array.F90 | 149 +++++++----- .../physics_inputs_host_var.F90 | 149 +++++++----- .../write_init_files/physics_inputs_mf.F90 | 177 ++++++++------ .../physics_inputs_no_horiz.F90 | 149 +++++++----- .../write_init_files/physics_inputs_noreq.F90 | 149 +++++++----- .../write_init_files/physics_inputs_param.F90 | 149 +++++++----- .../physics_inputs_protect.F90 | 149 +++++++----- .../physics_inputs_scalar.F90 | 149 +++++++----- .../physics_inputs_simple.F90 | 149 +++++++----- test/unit/test_build_cache.py | 4 +- test/unit/test_cam_autogen.py | 8 +- test/unit/test_registry.py | 18 +- test/unit/test_write_init_files.py | 40 +-- 25 files changed, 1448 insertions(+), 1091 deletions(-) diff --git a/cime_config/cam_autogen.py b/cime_config/cam_autogen.py index eeb31229..e5d7b32d 100644 --- a/cime_config/cam_autogen.py +++ b/cime_config/cam_autogen.py @@ -392,7 +392,7 @@ def generate_registry(data_search, build_cache, atm_root, bldroot, gen_fort_indent, source_mods_dir, atm_root, logger=_LOGGER, schema_paths=data_search, error_on_no_validate=True) - retcode, reg_file_list, ic_names = retvals + retcode, reg_file_list, ic_names, constituents = retvals # Raise error if gen_registry failed: if retcode != 0: emsg = "ERROR:Unable to generate CAM data structures from {}, err = {}" @@ -406,14 +406,15 @@ def generate_registry(data_search, build_cache, atm_root, bldroot, # Save build details in the build cache reg_file_paths = [x.file_path for x in reg_file_list if x.file_path] build_cache.update_registry(gen_reg_file, registry_files, dycore, - reg_file_paths, ic_names) + reg_file_paths, ic_names, constituents) else: # If we did not run the registry generator, retrieve info from cache reg_file_paths = build_cache.reg_file_list() ic_names = build_cache.ic_names() + constituents = build_cache.constituents() # End if - return genreg_dir, do_gen_registry, reg_file_paths, ic_names + return genreg_dir, do_gen_registry, reg_file_paths, ic_names, constituents ############################################################################### def generate_physics_suites(build_cache, preproc_defs, host_name, @@ -629,7 +630,7 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, ############################################################################### def generate_init_routines(build_cache, bldroot, force_ccpp, force_init, source_mods_dir, gen_fort_indent, - cap_database, ic_names): + cap_database, ic_names, constituents): ############################################################################### """ Generate the host model initialization source code files @@ -667,8 +668,8 @@ def generate_init_routines(build_cache, bldroot, force_ccpp, force_init, # within write_init_files (so that write_init_files can be the place # where the source include files are stored). source_paths = [source_mods_dir, _REG_GEN_DIR] - retmsg = write_init_files(cap_database, ic_names, init_dir, - _find_file, source_paths, + retmsg = write_init_files(cap_database, ic_names, constituents, + init_dir, _find_file, source_paths, gen_fort_indent, _LOGGER) #Check that script ran properly: diff --git a/cime_config/cam_build_cache.py b/cime_config/cam_build_cache.py index 2bda072e..70b31853 100644 --- a/cime_config/cam_build_cache.py +++ b/cime_config/cam_build_cache.py @@ -226,6 +226,7 @@ def __init__(self, build_cache): self.__kind_types = {} self.__reg_gen_files = [] self.__ic_names = {} + self.__constituents = [] if os.path.exists(build_cache): # Initialize build cache state _, cache = read_xml_file(build_cache) @@ -252,6 +253,10 @@ def __init__(self, build_cache): # end if itext = clean_xml_text(item) self.__ic_names[stdname].append(itext) + elif item.tag == 'constituent_entry': + stdname = item.get('standard_name') + itext = clean_xml_text(item) + self.__constituents.append(itext) else: emsg = "ERROR: Unknown registry tag, '{}'" raise ValueError(emsg.format(item.tag)) @@ -313,7 +318,7 @@ def __init__(self, build_cache): # end if def update_registry(self, gen_reg_file, registry_source_files, - dycore, reg_file_list, ic_names): + dycore, reg_file_list, ic_names, constituents): """Replace the registry cache data with input data """ self.__dycore = dycore @@ -328,6 +333,7 @@ def update_registry(self, gen_reg_file, registry_source_files, # ic_names are the initial condition variable names from the registry, # and should already be of type dict: self.__ic_names = ic_names + self.__constituents = constituents def update_ccpp(self, suite_definition_files, scheme_files, host_files, xml_files, namelist_meta_files, namelist_groups, @@ -400,6 +406,10 @@ def write(self): ic_entry.text = ic_name # end for # end for + for stdname in self.__constituents: + const_entry = ET.SubElement(registry, 'constituent_entry') + const_entry.text = stdname + # end for # CCPP ccpp = ET.SubElement(new_cache, 'CCPP') for sfile in self.__sdfs.values(): @@ -603,5 +613,9 @@ def ic_names(self): """Return a copy of the registry initial conditions dictionary""" return dict(self.__ic_names) + def constituents(self): + """Return a copy of the registry constituents list""" + return list(self.__constituents) + ############# # End of file diff --git a/cime_config/cam_config.py b/cime_config/cam_config.py index 80bef16e..d2a5fcb6 100644 --- a/cime_config/cam_config.py +++ b/cime_config/cam_config.py @@ -838,7 +838,7 @@ def generate_cam_src(self, gen_fort_indent): retvals = generate_registry(data_search, build_cache, self.__atm_root, self.__bldroot, source_mods_dir, dyn, gen_fort_indent) - reg_dir, force_ccpp, reg_files, ic_names = retvals + reg_dir, force_ccpp, reg_files, ic_names, constituents = retvals #Add registry path to config object: reg_dir_desc = "Location of auto-generated registry code." @@ -871,7 +871,7 @@ def generate_cam_src(self, gen_fort_indent): init_dir = generate_init_routines(build_cache, self.__bldroot, force_ccpp, force_init, source_mods_dir, gen_fort_indent, - capgen_db, ic_names) + capgen_db, ic_names, constituents) #Add registry path to config object: init_dir_desc = "Location of auto-generated physics initialization code." diff --git a/src/data/generate_registry_data.py b/src/data/generate_registry_data.py index 33adc954..022c176f 100755 --- a/src/data/generate_registry_data.py +++ b/src/data/generate_registry_data.py @@ -1733,6 +1733,31 @@ def _create_ic_name_dict(registry): # end for return ic_name_dict +############################################################################### +def _create_constituent_list(registry): +############################################################################### + """ + Create a list of all constituents found in the registry. + To be used by write_init_files.py - need to keep track + of all constituent variables, not just ones required by + CCPP metadata, to handle runtime constituents + """ + constituent_list = [] + for section in registry: + if section.tag == 'file': + for obj in section: + if obj.tag == 'variable': + if obj.get('constituent'): + stdname = obj.get('standard_name') + constituent_list.append(stdname) + # end if (ignore non-constituents) + # end if (ignore other node types) + # end for + # end if (ignore other node types) + # end for + return constituent_list + + ############################################################################### def gen_registry(registry_file, dycore, outdir, indent, src_mod, src_root, loglevel=None, logger=None, @@ -1802,6 +1827,7 @@ def gen_registry(registry_file, dycore, outdir, indent, retcode = 1 files = None ic_names = None + constituents = None else: library_name = registry.get('name') emsg = f"Parsing registry, {library_name}" @@ -1811,9 +1837,10 @@ def gen_registry(registry_file, dycore, outdir, indent, src_root, reg_dir, indent, logger) # See comment in _create_ic_name_dict ic_names = _create_ic_name_dict(registry) + constituents = _create_constituent_list(registry) retcode = 0 # Throw exception on error # end if - return retcode, files, ic_names + return retcode, files, ic_names, constituents def main(): """Function to execute when module called as a script""" diff --git a/src/data/write_init_files.py b/src/data/write_init_files.py index aa93962e..6bf443f0 100644 --- a/src/data/write_init_files.py +++ b/src/data/write_init_files.py @@ -46,7 +46,7 @@ #Main function ############## -def write_init_files(cap_database, ic_names, outdir, +def write_init_files(cap_database, ic_names, constituents, outdir, file_find_func, source_paths, indent, logger, phys_check_filename=None, phys_input_filename=None): @@ -130,7 +130,7 @@ def write_init_files(cap_database, ic_names, outdir, # Gather all the host model variables that are required by # any of the compiled CCPP physics suites. - host_vars, constituent_set, retmsg = gather_ccpp_req_vars(cap_database) + host_vars, constituent_set, retmsg = gather_ccpp_req_vars(cap_database, constituents) # Quit now if there are missing variables if retmsg: @@ -173,12 +173,12 @@ def write_init_files(cap_database, ic_names, outdir, # end for # Write public parameters: - retvals = write_ic_params(outfile, host_vars, ic_names) + retvals = write_ic_params(outfile, host_vars, ic_names, constituents) ic_names, ic_max_len, stdname_max_len = retvals # Write initial condition arrays: write_ic_arrays(outfile, ic_names, ic_max_len, - stdname_max_len, host_vars) + stdname_max_len, host_vars, constituents) # Add "contains" statement: outfile.end_module_header() @@ -244,7 +244,7 @@ def write_init_files(cap_database, ic_names, outdir, # Write physics_check_data subroutine: write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, - phys_check_fname_str, constituent_set) + phys_check_fname_str, constituent_set, constituents) # -------------------------------------- @@ -298,7 +298,7 @@ def _find_and_add_host_variable(stdname, host_dict, var_dict): return missing_vars ############################################################################## -def gather_ccpp_req_vars(cap_database): +def gather_ccpp_req_vars(cap_database, registry_constituents): """ Generate a list of host-model and constituent variables required by the CCPP physics suites potentially being used @@ -331,13 +331,12 @@ def gather_ccpp_req_vars(cap_database): (stdname not in req_vars) and (stdname not in _EXCLUDED_STDNAMES)): if is_const: - #Variable is a constituent, so may not be known - #until runtime, but still need variable names in order - #to read from a file if need be: - req_vars[stdname] = cvar - #Add variable to constituent set: constituent_vars.add(stdname) + #Add variable to required variable list if it's not a registry constituent + if stdname not in registry_constituents: + req_vars[stdname] = cvar + # end if else: # We need to work with the host model version of this variable missing = _find_and_add_host_variable(stdname, host_dict, @@ -359,7 +358,7 @@ def gather_ccpp_req_vars(cap_database): #FORTRAN WRITING FUNCTIONS ########################## -def write_ic_params(outfile, host_vars, ic_names): +def write_ic_params(outfile, host_vars, ic_names, constituents): """ Write public parameter declarations needed @@ -370,7 +369,7 @@ def write_ic_params(outfile, host_vars, ic_names): #Create new Fortran integer parameter to store total number of variables: outfile.comment("Total number of physics-related variables:", 1) - num_pvars = len(host_vars) + num_pvars = len(host_vars) + len(constituents) outfile.write(f"integer, public, parameter :: phys_var_num = {num_pvars}", 1) num_cvars = len(_EXCLUDED_STDNAMES) @@ -419,7 +418,7 @@ def write_ic_params(outfile, host_vars, ic_names): ###### def write_ic_arrays(outfile, ic_name_dict, ic_max_len, - stdname_max_len, host_vars): + stdname_max_len, host_vars, constituents): """ Write initial condition arrays to store @@ -428,7 +427,7 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, """ #Create variable name array string lists: - num_input_vars = len(host_vars) + num_input_vars = len(host_vars) + len(constituents) stdname_strs = [] ic_name_strs = [] @@ -445,6 +444,10 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, # for each variable with the proper length, : for hvar in host_vars: var_stdname = hvar.get_prop_value('standard_name') + if var_stdname in constituents: + # skip registry constituents; we'll tackle these after + continue + # end if # Create standard_name string with proper size, and append to list: stdname_strs.append(f"'{var_stdname: <{stdname_max_len}}'") @@ -465,6 +468,26 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, ic_name_strs.append(', '.join(f"'{n}'" for n in ic_names_with_spaces)) # end for + # Add any constituent variables: + for const in constituents: + stdname_strs.append(f"'{const: <{stdname_max_len}}'") + + #Extract input (IC) names list: + ic_names = ic_name_dict[const] + + # Determine number of IC names for variable: + ic_name_num = len(ic_names) + + #Pad the ic_names to ic_max_len: + ic_names_with_spaces = [f"{x: <{ic_max_len}}" for x in ic_names] + if ic_name_num < max_ic_num: + ic_names_with_spaces.extend(fake_ic_names[:-ic_name_num]) + # end if + + #Append new ic_names to string list: + ic_name_strs.append(', '.join(f"'{n}'" for n in ic_names_with_spaces)) + # end if + #Write arrays to Fortran file: #---------------------------- @@ -550,6 +573,17 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, #Write line to file: outfile.write(log_arr_str, 2) # end for + for var_num, var_name in enumerate(constituents): + # If at the end of the list, then update suffix: + if var_num == num_input_vars-len(host_vars)-1: + arr_suffix = ' /)' + # end if + #Set array values: + log_arr_str = '.false.' + arr_suffix + + #Write line to file: + outfile.write(log_arr_str, 2) + # end for outfile.blank_line() @@ -565,7 +599,6 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, #variable is a parameter: arr_suffix = ', &' for var_num, hvar in enumerate(host_vars): - var_stdname = hvar.get_prop_value('standard_name') #If at the end of the list, then update suffix: if var_num == num_input_vars-1: arr_suffix = ' /)' @@ -579,6 +612,16 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, #Write line to file: outfile.write(log_arr_str, 2) # end for + for var_num, varname in enumerate(constituents): + #If at the end of the list, then update suffix: + if var_num == num_input_vars-len(host_vars)-1: + arr_suffix = ' /)' + # end if + #Set array values: + log_arr_str = 'UNINITIALIZED' + arr_suffix + #Write line to file: + outfile.write(log_arr_str, 2) + # end for outfile.blank_line() #---------------------------- @@ -841,10 +884,13 @@ 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_model_const_properties"]], + ["cam_ccpp_cap", ["ccpp_physics_suite_variables", + "cam_constituents_array", + "cam_model_const_properties"]], ["ccpp_kinds", ["kind_phys"]], [phys_check_fname_str, ["phys_var_num", "phys_var_stdnames", - "input_var_names", "std_name_len"]], + "input_var_names", "std_name_len", + "is_initialized"]], ["ccpp_constituent_prop_mod", ["ccpp_constituent_prop_ptr_t"]], ["cam_logfile", ["iulog"]]] @@ -887,6 +933,7 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports, 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.write("character(len=std_name_len) :: std_name !Variable to hold constiutent standard name", 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) @@ -981,48 +1028,7 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports, # Handle the case where the required variable is a constituent outfile.write("case (const_idx)", 5) 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.blank_line() - outfile.comment("Check if constituent standard name in registered SIMA standard names list:", 6) - outfile.write("if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then", 6) - outfile.comment("Find array index to extract correct input names:", 7) - outfile.write("do n=1, phys_var_num", 7) - outfile.write("if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then", 8) - outfile.write("const_input_idx = n", 9) - outfile.write("exit", 9) - outfile.write("end if", 8) - outfile.write("end do", 7) - outfile.write("call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found)", 7) - outfile.write("else", 6) - outfile.comment("If not in standard names list, then just use constituent name as input file name:",7) - 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)", 7) - outfile.write("end if", 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) - 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 ', trim(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 ', trim(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.comment("If an index was found in the constituent hash table, then do nothing, this will be handled later", 6) outfile.blank_line() # start default case steps: @@ -1072,6 +1078,60 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports, # End suite loop: outfile.write(" end do !CCPP suites", 2) outfile.blank_line() + + # Read in constituent data + outfile.comment("Read in constituent variables if not using init variables", 2) + outfile.write("field_data_ptr => cam_constituents_array()", 2) + outfile.write("const_props => cam_model_const_properties()", 2) + outfile.blank_line() + outfile.comment("Iterate over all registered constituents", 2) + outfile.write("do constituent_idx = 1, size(const_props)", 2) + outfile.write("var_found = .false.", 3) + outfile.comment("Check if constituent standard name in registered SIMA standard names list:", 3) + outfile.write("call const_props(constituent_idx)%standard_name(std_name)", 3) + outfile.write("if(any(phys_var_stdnames == trim(std_name))) then", 3) + outfile.comment("Don't read the variable in if it's already initialized", 4) + outfile.write("if (is_initialized(std_name)) then", 4) + outfile.write("cycle", 5) + outfile.write("end if", 4) + outfile.comment("Find array index to extract correct input names:", 4) + outfile.write("do n=1, phys_var_num", 4) + outfile.write("if(trim(phys_var_stdnames(n)) == trim(std_name)) then", 5) + outfile.write("const_input_idx = n", 6) + outfile.write("exit", 6) + outfile.write("end if", 5) + outfile.write("end do", 4) + outfile.write("call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found)", 4) + outfile.write("else", 3) + outfile.comment("If not in standard names list, then just use constituent name as input file name:",4) + outfile.write("call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found)", 4) + outfile.write("end if", 3) + outfile.write("if(.not. var_found) then", 3) + outfile.write("constituent_has_default = .false.", 4) + outfile.write("call const_props(constituent_idx)%has_default(constituent_has_default, constituent_errflg, constituent_errmsg)", 4) + outfile.write("if (constituent_errflg /= 0) then", 4) + outfile.write("call endrun(constituent_errmsg, file=__FILE__, line=__LINE__)", 5) + outfile.write("end if", 4) + outfile.write("if (constituent_has_default) then", 4) + outfile.write("call const_props(constituent_idx)%default_value(constituent_default_value, constituent_errflg, constituent_errmsg)", 5) + outfile.write("if (constituent_errflg /= 0) then", 5) + outfile.write("call endrun(constituent_errmsg, file=__FILE__, line=__LINE__)", 6) + outfile.write("end if", 5) + outfile.write("field_data_ptr(:,:,constituent_idx) = constituent_default_value", 5) + outfile.write("if (masterproc) then", 5) + outfile.write("write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value", 6) + outfile.write("end if", 5) + outfile.write("else", 4) + outfile.write("field_data_ptr(:,:,constituent_idx) = 0._kind_phys", 5) + outfile.write("if (masterproc) then", 5) + outfile.write("write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.'", 6) + outfile.write("end if", 5) + outfile.write("end if", 4) + outfile.write("end if", 3) + outfile.write("end do", 2) + outfile.blank_line() + + # start default case steps: # End subroutine: outfile.write("end subroutine physics_read_data", 1) @@ -1081,7 +1141,7 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports, ##### def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, - phys_check_fname_str, constituent_set): + phys_check_fname_str, constituent_set, constituents): """ Write the "physics_check_data" subroutine, which @@ -1149,7 +1209,9 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, ["physics_data", ["check_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_advected_constituents_array"]], + ["cam_ccpp_cap", ["ccpp_physics_suite_variables", + "cam_advected_constituents_array", + "cam_model_const_properties"]], ["cam_constituents", ["const_get_index"]], ["ccpp_kinds", ["kind_phys"]], ["cam_logfile", ["iulog"]], @@ -1157,6 +1219,7 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, ["phys_vars_init_check", ["is_read_from_file"]], ["ioFileMod", ["cam_get_file"]], ["cam_pio_utils", ["cam_pio_openfile", "cam_pio_closefile"]], + ["ccpp_constituent_prop_mod", ["ccpp_constituent_prop_ptr_t"]], [phys_check_fname_str, ["phys_var_num", "phys_var_stdnames", "input_var_names", @@ -1204,7 +1267,9 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, outfile.write("logical :: file_found", 2) outfile.write("logical :: is_first", 2) outfile.write("logical :: is_read", 2) + outfile.write("character(len=std_name_len) :: std_name !Variable to hold constiutent standard name", 2) outfile.write("real(kind=kind_phys), pointer :: field_data_ptr(:,:,:)", 2) + outfile.write("type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:)", 2) outfile.blank_line() # Initialize variables: @@ -1268,24 +1333,7 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, outfile.comment("First check if the required variable is a constituent:", 4) outfile.write("call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.)", 4) outfile.write("if (constituent_idx > -1) then", 4) - outfile.comment("The required variable is a constituent. Call check variable routine on the relevant index of the constituent array", 5) - outfile.write("field_data_ptr => cam_advected_constituents_array()", 5) - outfile.blank_line() - outfile.comment("Check if constituent standard name in registered SIMA standard names list:", 5) - outfile.write("if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then", 5) - outfile.comment("Find array index to extract correct input names:", 6) - outfile.write("do n=1, phys_var_num", 6) - outfile.write("if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then", 7) - outfile.write("const_input_idx = n", 8) - outfile.write("exit", 8) - outfile.write("end if", 7) - outfile.write("end do", 6) - outfile.write("call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), ccpp_required_data(req_idx), min_difference, min_relative_value, is_first)", 6) - outfile.write("else", 5) - outfile.comment("If not in standard names list, then just use constituent name as input file name:",6) - outfile.write("call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), ccpp_required_data(req_idx), min_difference, min_relative_value, is_first)", 6) - outfile.write("end if", 5) - + outfile.write("cycle", 5) outfile.write("else", 4) outfile.comment("The required variable is not a constituent. Check if the variable was read from a file", 5) @@ -1321,6 +1369,27 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, # End suite loop: outfile.write("end do !CCPP suites", 2) outfile.blank_line() + outfile.comment("Check constituent variables", 2) + outfile.write("field_data_ptr => cam_advected_constituents_array()", 2) + outfile.write("const_props => cam_model_const_properties()", 2) + outfile.blank_line() + outfile.write("do constituent_idx = 1, size(const_props)", 2) + outfile.comment("Check if constituent standard name in registered SIMA standard names list:", 3) + outfile.write("call const_props(constituent_idx)%standard_name(std_name)", 3) + outfile.write("if(any(phys_var_stdnames == std_name)) then", 3) + outfile.comment("Find array index to extract correct input names:", 4) + outfile.write("do n=1, phys_var_num", 4) + outfile.write("if(trim(phys_var_stdnames(n)) == trim(std_name)) then", 5) + outfile.write("const_input_idx = n", 6) + outfile.write("exit", 6) + outfile.write("end if", 5) + outfile.write("end do", 4) + outfile.write("call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, is_first)", 4) + outfile.write("else", 3) + outfile.comment("If not in standard names list, then just use constituent name as input file name:",4) + outfile.write("call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, is_first)", 4) + outfile.write("end if", 3) + outfile.write("end do", 2) # Close check file outfile.comment("Close check file:", 2) diff --git a/test/unit/sample_files/build_cache_files/update_reg_build_cache.xml b/test/unit/sample_files/build_cache_files/update_reg_build_cache.xml index e773ee2c..5a4273b9 100644 --- a/test/unit/sample_files/build_cache_files/update_reg_build_cache.xml +++ b/test/unit/sample_files/build_cache_files/update_reg_build_cache.xml @@ -8,6 +8,8 @@ tmp/cam_build_cache/test_reg.xml heart brain + cnst_1 + cnst_2 diff --git a/test/unit/sample_files/write_init_files/phys_vars_init_check_cnst.F90 b/test/unit/sample_files/write_init_files/phys_vars_init_check_cnst.F90 index 365fe4c7..515e0307 100644 --- a/test/unit/sample_files/write_init_files/phys_vars_init_check_cnst.F90 +++ b/test/unit/sample_files/write_init_files/phys_vars_init_check_cnst.F90 @@ -40,7 +40,7 @@ module phys_vars_init_check_cnst integer, public, parameter :: std_name_len = 25 ! Max length of input (IC) file variable names: - integer, public, parameter :: ic_name_len = 13 + integer, public, parameter :: ic_name_len = 12 ! Physics-related input variable standard names: character(len=25), public, protected :: phys_var_stdnames(phys_var_num) = (/ & @@ -65,10 +65,10 @@ module phys_vars_init_check_cnst "suite_name ", & "suite_part " /) !Array storing all registered IC file input names for each variable: - character(len=13), public, protected :: input_var_names(2, phys_var_num) = reshape((/ & - 'theta ', 'pot_temp ', & - 'slp ', 'sea_lev_pres ', & - 'COOL_CAT ', 'cnst_COOL_CAT' /), (/2, phys_var_num/)) + character(len=12), public, protected :: input_var_names(2, phys_var_num) = reshape((/ & + 'theta ', 'pot_temp ', & + 'slp ', 'sea_lev_pres', & + 'COOL_CAT ', 'cnst_COOL_CAT' /), (/2, phys_var_num/)) ! Array indicating whether or not variable is protected: logical, public, protected :: protected_vars(phys_var_num)= (/ & diff --git a/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 b/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 index 75efc762..fcb3802a 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_4D, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_4D, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_4D, only: slp, theta @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,23 +169,76 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) - use pio, only: file_desc_t, pio_nowrite - use cam_abortutils, only: endrun - use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX - use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array - use cam_constituents, only: const_get_index - use ccpp_kinds, only: kind_phys - use cam_logfile, only: iulog - use spmd_utils, only: masterproc - use phys_vars_init_check, only: is_read_from_file - use ioFileMod, only: cam_get_file - use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile - use phys_vars_init_check_4D, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len - use physics_types_4D, only: slp, theta + use pio, only: file_desc_t, pio_nowrite + use cam_abortutils, only: endrun + use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX + use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties + use cam_constituents, only: const_get_index + use ccpp_kinds, only: kind_phys + use cam_logfile, only: iulog + use spmd_utils, only: masterproc + use phys_vars_init_check, only: is_read_from_file + use ioFileMod, only: cam_get_file + use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t + use phys_vars_init_check_4D, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use physics_types_4D, only: slp, theta ! Dummy arguments character(len=SHR_KIND_CL), intent(in) :: file_name @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -344,6 +338,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 b/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 index 46cc2b53..5bf9cf29 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_bvd, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_bvd, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_bad_vertdim, only: slp, theta @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,6 +169,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -219,7 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -227,6 +236,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_bvd, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_bad_vertdim, only: slp, theta @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -344,6 +338,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 b/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 index 2289adfd..7c830ac2 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_cnst, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_cnst, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_simple, only: slp, theta @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,6 +169,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -219,7 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -227,6 +236,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_cnst, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_simple, only: slp, theta @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -345,6 +339,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 index de9adfea..1810ede6 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_ddt, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_ddt, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_ddt, only: phys_state, slp @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,23 +169,76 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) - use pio, only: file_desc_t, pio_nowrite - use cam_abortutils, only: endrun - use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX - use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array - use cam_constituents, only: const_get_index - use ccpp_kinds, only: kind_phys - use cam_logfile, only: iulog - use spmd_utils, only: masterproc - use phys_vars_init_check, only: is_read_from_file - use ioFileMod, only: cam_get_file - use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile - use phys_vars_init_check_ddt, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len - use physics_types_ddt, only: phys_state, slp + use pio, only: file_desc_t, pio_nowrite + use cam_abortutils, only: endrun + use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX + use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties + use cam_constituents, only: const_get_index + use ccpp_kinds, only: kind_phys + use cam_logfile, only: iulog + use spmd_utils, only: masterproc + use phys_vars_init_check, only: is_read_from_file + use ioFileMod, only: cam_get_file + use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t + use phys_vars_init_check_ddt, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use physics_types_ddt, only: phys_state, slp ! Dummy arguments character(len=SHR_KIND_CL), intent(in) :: file_name @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -345,6 +339,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 index 2dc7d3b9..ba66a2cf 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_ddt2, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_ddt2, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_ddt2, only: phys_state @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,6 +169,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -219,7 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -227,6 +236,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_ddt2, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_ddt2, only: phys_state @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -345,6 +339,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 index 620eceed..dd7140bb 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_ddt_array, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_ddt_array, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_ddt_array, only: ix_theta, phys_state @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,6 +169,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -219,7 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -227,6 +236,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_ddt_array, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_ddt_array, only: ix_theta, phys_state @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -345,6 +339,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 b/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 index 34d18e84..484c4007 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_host_var, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_host_var, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_host_var, only: slp @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -209,6 +166,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -216,7 +225,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -224,6 +233,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_host_var, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_host_var, only: slp @@ -257,7 +267,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -296,25 +308,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -338,6 +332,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 b/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 index 868c512b..73667769 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_mf, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_mf, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use ref_theta, only: theta @@ -70,6 +70,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -134,51 +135,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -213,24 +170,77 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) - use pio, only: file_desc_t, pio_nowrite - use cam_abortutils, only: endrun - use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX - use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array - use cam_constituents, only: const_get_index - use ccpp_kinds, only: kind_phys - use cam_logfile, only: iulog - use spmd_utils, only: masterproc - use phys_vars_init_check, only: is_read_from_file - use ioFileMod, only: cam_get_file - use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile - use phys_vars_init_check_mf, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len - use ref_theta, only: theta - use physics_types_mf, only: slp + use pio, only: file_desc_t, pio_nowrite + use cam_abortutils, only: endrun + use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX + use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties + use cam_constituents, only: const_get_index + use ccpp_kinds, only: kind_phys + use cam_logfile, only: iulog + use spmd_utils, only: masterproc + use phys_vars_init_check, only: is_read_from_file + use ioFileMod, only: cam_get_file + use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t + use phys_vars_init_check_mf, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use ref_theta, only: theta + use physics_types_mf, only: slp ! Dummy arguments character(len=SHR_KIND_CL), intent(in) :: file_name @@ -262,7 +272,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -301,25 +313,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -347,6 +341,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 b/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 index 96453a7f..c229e563 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_no_horiz, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_no_horiz, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_no_horiz, only: slp, theta @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,6 +169,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -219,7 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -227,6 +236,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_no_horiz, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_no_horiz, only: slp, theta @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -344,6 +338,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 b/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 index 2d532a63..a1703efe 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_noreq, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_noreq, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog @@ -68,6 +68,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -132,51 +133,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -205,6 +162,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -212,7 +221,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -220,6 +229,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_noreq, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len ! Dummy arguments @@ -252,7 +262,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -291,25 +303,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -329,6 +323,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_param.F90 b/test/unit/sample_files/write_init_files/physics_inputs_param.F90 index 0136b24c..ab098ff6 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_param.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_param.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_param, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_param, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_param, only: g, slp, theta @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -215,6 +172,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -222,7 +231,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -230,6 +239,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_param, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_param, only: g, slp, theta @@ -263,7 +273,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -302,25 +314,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -351,6 +345,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 b/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 index b5c6e5f4..d0395c3a 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_protect, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_protect, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_protected, only: slp, theta @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,6 +169,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -219,7 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -227,6 +236,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_protect, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_protected, only: slp, theta @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -345,6 +339,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 b/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 index 065fb36f..07ca4c12 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_scalar, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_scalar, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_scalar_var, only: slp, theta @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,6 +169,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -219,7 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -227,6 +236,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_scalar, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_scalar_var, only: slp, theta @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -344,6 +338,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 b/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 index f4eb298c..37e8cb6f 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 @@ -36,7 +36,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia use physics_data, only: read_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_constituents_array, cam_model_const_properties use ccpp_kinds, only: kind_phys - use phys_vars_init_check_simple, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len + use phys_vars_init_check_simple, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len, is_initialized use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use cam_logfile, only: iulog use physics_types_simple, only: slp, theta @@ -69,6 +69,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia 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 + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name ! Fields needed for getting default data value for constituents type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) @@ -133,51 +134,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia case (const_idx) - ! 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() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call read_field(file, ccpp_required_data(req_idx), input_var_names(:,const_input_idx), 'lev', timestep, & - field_data_ptr(:,:,constituent_idx), mark_as_read=.false., error_on_not_found=.false., var_found=var_found) - else - ! If not in standard names list, then just use constituent name as input file name: - 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) - end if - 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) - 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 ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' - end if - end if - end if + ! If an index was found in the constituent hash table, then do nothing, this will be handled later case default @@ -212,6 +169,58 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end do !CCPP suites + ! Read in constituent variables if not using init variables + field_data_ptr => cam_constituents_array() + const_props => cam_model_const_properties() + + ! Iterate over all registered constituents + do constituent_idx = 1, size(const_props) + var_found = .false. + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == trim(std_name))) then + ! Don't read the variable in if it's already initialized + if (is_initialized(std_name)) then + cycle + end if + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call read_field(file, std_name, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & + mark_as_read=.false., error_on_not_found=.false., var_found=var_found) + else + ! If not in standard names list, then just use constituent name as input file name: + call read_field(file, std_name, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), mark_as_read=.false., & + error_on_not_found=.false., var_found=var_found) + end if + if(.not. var_found) then + 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) + 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,*) 'Constituent ', trim(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 ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + end if + end if + end if + end do + end subroutine physics_read_data subroutine physics_check_data(file_name, suite_names, timestep, min_difference, min_relative_value) @@ -219,7 +228,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use cam_abortutils, only: endrun use shr_kind_mod, only: SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX use physics_data, only: check_field, find_input_name_idx, no_exist_idx, init_mark_idx, prot_no_init_idx, const_idx - use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array + use cam_ccpp_cap, only: ccpp_physics_suite_variables, cam_advected_constituents_array, cam_model_const_properties use cam_constituents, only: const_get_index use ccpp_kinds, only: kind_phys use cam_logfile, only: iulog @@ -227,6 +236,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, use phys_vars_init_check, only: is_read_from_file use ioFileMod, only: cam_get_file use cam_pio_utils, only: cam_pio_openfile, cam_pio_closefile + use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t use phys_vars_init_check_simple, only: phys_var_num, phys_var_stdnames, input_var_names, std_name_len use physics_types_simple, only: slp, theta @@ -260,7 +270,9 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, logical :: file_found logical :: is_first logical :: is_read + character(len=std_name_len) :: std_name !Variable to hold constiutent standard name real(kind=kind_phys), pointer :: field_data_ptr(:,:,:) + type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) ! Initalize missing and non-initialized variables strings: missing_required_vars = ' ' @@ -299,25 +311,7 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, ! First check if the required variable is a constituent: call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.) if (constituent_idx > -1) then - ! The required variable is a constituent. Call check variable routine on the relevant index of the constituent array - field_data_ptr => cam_advected_constituents_array() - - ! Check if constituent standard name in registered SIMA standard names list: - if(any(phys_var_stdnames == ccpp_required_data(req_idx))) then - ! Find array index to extract correct input names: - do n=1, phys_var_num - if(trim(phys_var_stdnames(n)) == trim(ccpp_required_data(req_idx))) then - const_input_idx = n - exit - end if - end do - call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - else - ! If not in standard names list, then just use constituent name as input file name: - call check_field(file, [ccpp_required_data(req_idx)], 'lev', timestep, field_data_ptr(:,:,constituent_idx), & - ccpp_required_data(req_idx), min_difference, min_relative_value, is_first) - end if + cycle else ! The required variable is not a constituent. Check if the variable was read from a file ! Find IC file input name array index for required variable: @@ -345,6 +339,29 @@ subroutine physics_check_data(file_name, suite_names, timestep, min_difference, end do !CCPP suites + ! Check constituent variables + field_data_ptr => cam_advected_constituents_array() + const_props => cam_model_const_properties() + + do constituent_idx = 1, size(const_props) + ! Check if constituent standard name in registered SIMA standard names list: + call const_props(constituent_idx)%standard_name(std_name) + if(any(phys_var_stdnames == std_name)) then + ! Find array index to extract correct input names: + do n=1, phys_var_num + if(trim(phys_var_stdnames(n)) == trim(std_name)) then + const_input_idx = n + exit + end if + end do + call check_field(file, input_var_names(:,const_input_idx), 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, & + min_difference, min_relative_value, is_first) + else + ! If not in standard names list, then just use constituent name as input file name: + call check_field(file, [std_name], 'lev', timestep, field_data_ptr(:,:,constituent_idx), std_name, min_difference, min_relative_value, & + is_first) + end if + end do ! Close check file: call cam_pio_closefile(file) deallocate(file) diff --git a/test/unit/test_build_cache.py b/test/unit/test_build_cache.py index c3152367..cb9ad96c 100644 --- a/test/unit/test_build_cache.py +++ b/test/unit/test_build_cache.py @@ -425,9 +425,11 @@ def test_update_registry(self): ic_names = {"Only_had_a": ["heart", "brain"]} dycore = "banana" + constituents = ['cnst_1', 'cnst_2'] + #Update registry fields: test_cache.update_registry(tmp_test_reg, [tmp_test_reg], - dycore, [tmp_test_reg], ic_names) + dycore, [tmp_test_reg], ic_names, constituents) #Write updated fields to build cache file: test_cache.write() diff --git a/test/unit/test_cam_autogen.py b/test/unit/test_cam_autogen.py index 58f54daa..4a786aab 100644 --- a/test/unit/test_cam_autogen.py +++ b/test/unit/test_cam_autogen.py @@ -158,6 +158,10 @@ def ic_names(self): return {} + def constituents(self): + """Fake version of 'constituents' property.""" + return [] + # pylint: enable=no-self-use # pylint: enable=unused-argument @@ -515,7 +519,7 @@ def test_generate_registry(self): test_data_search = [os.path.join(_CAM_ROOT_DIR, "src", "data")] #Set expected output tuple: - expected_results = (f'{self.test_bldroot}'+os.sep+'cam_registry', False, [], {}) + expected_results = (f'{self.test_bldroot}'+os.sep+'cam_registry', False, [], {}, []) #Run registry generation function: gen_results = generate_registry(test_data_search, self.test_cache, _CAM_ROOT_DIR, @@ -670,7 +674,7 @@ def test_generate_init_routines(self): #Run init routines generation function: gen_path = generate_init_routines(self.test_cache, self.test_bldroot, False, False, - self.test_src_mods_dir, self.fort_indent, None, {}) + self.test_src_mods_dir, self.fort_indent, None, {}, []) #Check that the output path matches what is expected: self.assertEqual(gen_path, expected_path) diff --git a/test/unit/test_registry.py b/test/unit/test_registry.py index 98d0a232..fcb19d04 100644 --- a/test/unit/test_registry.py +++ b/test/unit/test_registry.py @@ -94,7 +94,7 @@ def test_good_simple_registry(self): out_meta = os.path.join(_TMP_DIR, out_source_name + '.meta') remove_files([out_source, out_meta]) # Run test - retcode, files, _ = gen_registry(filename, 'fv', _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, 'fv', _TMP_DIR, 2, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -136,7 +136,7 @@ def test_good_ddt_registry(self): out_meta = os.path.join(_TMP_DIR, out_meta_name) remove_files([out_source, out_meta]) # Run dycore - retcode, files, _ = gen_registry(filename, dycore, _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, dycore, _TMP_DIR, 2, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -183,7 +183,7 @@ def test_good_ddt_registry2(self): out_meta = os.path.join(_TMP_DIR, out_meta_name) remove_files([out_source, out_meta]) # Run dycore - retcode, files, _ = gen_registry(filename, 'se', _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 2, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -223,7 +223,7 @@ def test_good_array(self): out_meta = os.path.join(_TMP_DIR, out_meta_name) remove_files([out_source, out_meta]) # Run dycore - retcode, files, _ = gen_registry(filename, 'se', _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 2, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -261,7 +261,7 @@ def test_good_metadata_file_registry(self): out_meta = os.path.join(_TMP_DIR, out_name + '.meta') remove_files([out_source, out_meta]) # generate registry - retcode, files, _ = gen_registry(filename, 'se', _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 2, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -315,7 +315,7 @@ def test_diff_src_root_metadata_file_registry(self): shutil.copy(meta_file, tmp_src_dir) # Generate registry - retcode, files, _ = gen_registry(filename, 'se', _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 2, _SRC_MOD_DIR, _TMP_DIR, loglevel=logging.ERROR, error_on_no_validate=True) @@ -372,7 +372,7 @@ def test_SourceMods_metadata_file_registry(self): shutil.copy(meta_file, source_mod_file) # Generate registry - retcode, files, _ = gen_registry(filename, 'se', _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 2, tmp_src_dir, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -423,7 +423,7 @@ def test_good_complete_registry(self): remove_files([out_source, out_meta]) # Run test - retcode, files, _ = gen_registry(filename, 'se', _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 2, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -530,7 +530,7 @@ def test_parameter(self): # End for tree.write(filename) # Run test - retcode, files, _ = gen_registry(filename, 'eul', _TMP_DIR, 2, + retcode, files, _, _ = gen_registry(filename, 'eul', _TMP_DIR, 2, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) diff --git a/test/unit/test_write_init_files.py b/test/unit/test_write_init_files.py index 86351216..1150192e 100644 --- a/test/unit/test_write_init_files.py +++ b/test/unit/test_write_init_files.py @@ -175,7 +175,7 @@ def test_simple_reg_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -238,7 +238,7 @@ def test_simple_reg_constituent_write_init(self): check_init_out, phys_input_out]) # Generate registry files: - _, _, ic_names = gen_registry(filename, 'se', _TMP_DIR, 3, + _, _, ic_names, constituents = gen_registry(filename, 'se', _TMP_DIR, 3, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -258,7 +258,7 @@ def test_simple_reg_constituent_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, ic_names, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, ic_names, constituents, _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -340,7 +340,7 @@ def test_no_reqvar_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -403,7 +403,7 @@ def test_protected_reg_write_init(self): check_init_out, phys_input_out]) # Generate registry files: - _, files, _ = gen_registry(filename, 'se', _TMP_DIR, 3, + _, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 3, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -423,7 +423,7 @@ def test_protected_reg_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -507,7 +507,7 @@ def test_host_input_var_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -572,7 +572,7 @@ def test_no_horiz_var_write_init(self): remove_files([out_source, out_meta, cap_datafile, check_init_out, phys_input_out]) # Generate registry files: - _, files, _ = gen_registry(filename, 'se', _TMP_DIR, 3, + _, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 3, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -592,7 +592,7 @@ def test_no_horiz_var_write_init(self): cap_database = capgen(run_env, return_db=True) # Run test - _ = write_init.write_init_files(cap_database, {}, _TMP_DIR, + _ = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -647,7 +647,7 @@ def test_scalar_var_write_init(self): check_init_out, phys_input_out]) # Generate registry files: - _, files, _ = gen_registry(filename, 'se', _TMP_DIR, 3, + _, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 3, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -667,7 +667,7 @@ def test_scalar_var_write_init(self): cap_database = capgen(run_env, return_db=True) # Run test - _ = write_init.write_init_files(cap_database, {}, _TMP_DIR, + _ = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -722,7 +722,7 @@ def test_4d_var_write_init(self): check_init_out, phys_input_out]) # Generate registry files: - _, files, _ = gen_registry(filename, 'se', _TMP_DIR, 3, + _, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 3, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -741,7 +741,7 @@ def test_4d_var_write_init(self): cap_database = capgen(run_env, return_db=True) # Run test - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -815,7 +815,7 @@ def test_ddt_reg_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -878,7 +878,7 @@ def test_ddt2_reg_write_init(self): check_init_out, phys_input_out]) # Generate registry files: - _, files, _ = gen_registry(filename, 'se', _TMP_DIR, 3, + _, files, _, _ = gen_registry(filename, 'se', _TMP_DIR, 3, _SRC_MOD_DIR, _CAM_ROOT, loglevel=logging.ERROR, error_on_no_validate=True) @@ -897,7 +897,7 @@ def test_ddt2_reg_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -978,7 +978,7 @@ def test_ddt_array_reg_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -1059,7 +1059,7 @@ def test_meta_file_reg_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -1140,7 +1140,7 @@ def test_parameter_reg_write_init(self): cap_database = capgen(run_env, return_db=True) # Generate physics initialization files: - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, @@ -1224,7 +1224,7 @@ def test_bad_vertical_dimension(self): cap_database = capgen(run_env, return_db=True) # Run test - retmsg = write_init.write_init_files(cap_database, {}, _TMP_DIR, + retmsg = write_init.write_init_files(cap_database, {}, [], _TMP_DIR, find_file, _INC_SEARCH_DIRS, 3, logger, phys_check_filename=vic_name, From 28becd1e95ab0277c4736d9cbc50428fd6e88f03 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Thu, 19 Sep 2024 19:11:41 -0600 Subject: [PATCH 02/11] clarify variable name --- cime_config/cam_autogen.py | 12 ++++++------ cime_config/cam_config.py | 4 ++-- src/data/generate_registry_data.py | 4 ++-- src/data/write_init_files.py | 28 ++++++++++++++-------------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cime_config/cam_autogen.py b/cime_config/cam_autogen.py index e5d7b32d..7cc1d9f1 100644 --- a/cime_config/cam_autogen.py +++ b/cime_config/cam_autogen.py @@ -392,7 +392,7 @@ def generate_registry(data_search, build_cache, atm_root, bldroot, gen_fort_indent, source_mods_dir, atm_root, logger=_LOGGER, schema_paths=data_search, error_on_no_validate=True) - retcode, reg_file_list, ic_names, constituents = retvals + retcode, reg_file_list, ic_names, registry_constituents = retvals # Raise error if gen_registry failed: if retcode != 0: emsg = "ERROR:Unable to generate CAM data structures from {}, err = {}" @@ -406,15 +406,15 @@ def generate_registry(data_search, build_cache, atm_root, bldroot, # Save build details in the build cache reg_file_paths = [x.file_path for x in reg_file_list if x.file_path] build_cache.update_registry(gen_reg_file, registry_files, dycore, - reg_file_paths, ic_names, constituents) + reg_file_paths, ic_names, registry_constituents) else: # If we did not run the registry generator, retrieve info from cache reg_file_paths = build_cache.reg_file_list() ic_names = build_cache.ic_names() - constituents = build_cache.constituents() + registry_constituents = build_cache.constituents() # End if - return genreg_dir, do_gen_registry, reg_file_paths, ic_names, constituents + return genreg_dir, do_gen_registry, reg_file_paths, ic_names, registry_constituents ############################################################################### def generate_physics_suites(build_cache, preproc_defs, host_name, @@ -630,7 +630,7 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, ############################################################################### def generate_init_routines(build_cache, bldroot, force_ccpp, force_init, source_mods_dir, gen_fort_indent, - cap_database, ic_names, constituents): + cap_database, ic_names, registry_constituents): ############################################################################### """ Generate the host model initialization source code files @@ -668,7 +668,7 @@ def generate_init_routines(build_cache, bldroot, force_ccpp, force_init, # within write_init_files (so that write_init_files can be the place # where the source include files are stored). source_paths = [source_mods_dir, _REG_GEN_DIR] - retmsg = write_init_files(cap_database, ic_names, constituents, + retmsg = write_init_files(cap_database, ic_names, registry_constituents, init_dir, _find_file, source_paths, gen_fort_indent, _LOGGER) diff --git a/cime_config/cam_config.py b/cime_config/cam_config.py index d2a5fcb6..afb298a9 100644 --- a/cime_config/cam_config.py +++ b/cime_config/cam_config.py @@ -838,7 +838,7 @@ def generate_cam_src(self, gen_fort_indent): retvals = generate_registry(data_search, build_cache, self.__atm_root, self.__bldroot, source_mods_dir, dyn, gen_fort_indent) - reg_dir, force_ccpp, reg_files, ic_names, constituents = retvals + reg_dir, force_ccpp, reg_files, ic_names, registry_constituents = retvals #Add registry path to config object: reg_dir_desc = "Location of auto-generated registry code." @@ -871,7 +871,7 @@ def generate_cam_src(self, gen_fort_indent): init_dir = generate_init_routines(build_cache, self.__bldroot, force_ccpp, force_init, source_mods_dir, gen_fort_indent, - capgen_db, ic_names, constituents) + capgen_db, ic_names, registry_constituents) #Add registry path to config object: init_dir_desc = "Location of auto-generated physics initialization code." diff --git a/src/data/generate_registry_data.py b/src/data/generate_registry_data.py index 022c176f..79c2ff5a 100755 --- a/src/data/generate_registry_data.py +++ b/src/data/generate_registry_data.py @@ -1837,10 +1837,10 @@ def gen_registry(registry_file, dycore, outdir, indent, src_root, reg_dir, indent, logger) # See comment in _create_ic_name_dict ic_names = _create_ic_name_dict(registry) - constituents = _create_constituent_list(registry) + registry_constituents = _create_constituent_list(registry) retcode = 0 # Throw exception on error # end if - return retcode, files, ic_names, constituents + return retcode, files, ic_names, registry_constituents def main(): """Function to execute when module called as a script""" diff --git a/src/data/write_init_files.py b/src/data/write_init_files.py index 6bf443f0..500787ab 100644 --- a/src/data/write_init_files.py +++ b/src/data/write_init_files.py @@ -46,7 +46,7 @@ #Main function ############## -def write_init_files(cap_database, ic_names, constituents, outdir, +def write_init_files(cap_database, ic_names, registry_constituents, outdir, file_find_func, source_paths, indent, logger, phys_check_filename=None, phys_input_filename=None): @@ -130,7 +130,7 @@ def write_init_files(cap_database, ic_names, constituents, outdir, # Gather all the host model variables that are required by # any of the compiled CCPP physics suites. - host_vars, constituent_set, retmsg = gather_ccpp_req_vars(cap_database, constituents) + host_vars, constituent_set, retmsg = gather_ccpp_req_vars(cap_database, registry_constituents) # Quit now if there are missing variables if retmsg: @@ -173,12 +173,12 @@ def write_init_files(cap_database, ic_names, constituents, outdir, # end for # Write public parameters: - retvals = write_ic_params(outfile, host_vars, ic_names, constituents) + retvals = write_ic_params(outfile, host_vars, ic_names, registry_constituents) ic_names, ic_max_len, stdname_max_len = retvals # Write initial condition arrays: write_ic_arrays(outfile, ic_names, ic_max_len, - stdname_max_len, host_vars, constituents) + stdname_max_len, host_vars, registry_constituents) # Add "contains" statement: outfile.end_module_header() @@ -244,7 +244,7 @@ def write_init_files(cap_database, ic_names, constituents, outdir, # Write physics_check_data subroutine: write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, - phys_check_fname_str, constituent_set, constituents) + phys_check_fname_str, constituent_set) # -------------------------------------- @@ -358,7 +358,7 @@ def gather_ccpp_req_vars(cap_database, registry_constituents): #FORTRAN WRITING FUNCTIONS ########################## -def write_ic_params(outfile, host_vars, ic_names, constituents): +def write_ic_params(outfile, host_vars, ic_names, registry_constituents): """ Write public parameter declarations needed @@ -369,7 +369,7 @@ def write_ic_params(outfile, host_vars, ic_names, constituents): #Create new Fortran integer parameter to store total number of variables: outfile.comment("Total number of physics-related variables:", 1) - num_pvars = len(host_vars) + len(constituents) + num_pvars = len(host_vars) + len(registry_constituents) outfile.write(f"integer, public, parameter :: phys_var_num = {num_pvars}", 1) num_cvars = len(_EXCLUDED_STDNAMES) @@ -418,7 +418,7 @@ def write_ic_params(outfile, host_vars, ic_names, constituents): ###### def write_ic_arrays(outfile, ic_name_dict, ic_max_len, - stdname_max_len, host_vars, constituents): + stdname_max_len, host_vars, registry_constituents): """ Write initial condition arrays to store @@ -427,7 +427,7 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, """ #Create variable name array string lists: - num_input_vars = len(host_vars) + len(constituents) + num_input_vars = len(host_vars) + len(registry_constituents) stdname_strs = [] ic_name_strs = [] @@ -444,7 +444,7 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, # for each variable with the proper length, : for hvar in host_vars: var_stdname = hvar.get_prop_value('standard_name') - if var_stdname in constituents: + if var_stdname in registry_constituents: # skip registry constituents; we'll tackle these after continue # end if @@ -469,7 +469,7 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, # end for # Add any constituent variables: - for const in constituents: + for const in registry_constituents: stdname_strs.append(f"'{const: <{stdname_max_len}}'") #Extract input (IC) names list: @@ -573,7 +573,7 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, #Write line to file: outfile.write(log_arr_str, 2) # end for - for var_num, var_name in enumerate(constituents): + for var_num, var_name in enumerate(registry_constituents): # If at the end of the list, then update suffix: if var_num == num_input_vars-len(host_vars)-1: arr_suffix = ' /)' @@ -612,7 +612,7 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, #Write line to file: outfile.write(log_arr_str, 2) # end for - for var_num, varname in enumerate(constituents): + for var_num, varname in enumerate(registry_constituents): #If at the end of the list, then update suffix: if var_num == num_input_vars-len(host_vars)-1: arr_suffix = ' /)' @@ -1141,7 +1141,7 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports, ##### def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, - phys_check_fname_str, constituent_set, constituents): + phys_check_fname_str, constituent_set): """ Write the "physics_check_data" subroutine, which From 75cdffbdf84c4b3542758cf089ff4e76d5366e6a Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Thu, 19 Sep 2024 19:24:27 -0600 Subject: [PATCH 03/11] fix bug from copied code --- src/data/write_init_files.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/write_init_files.py b/src/data/write_init_files.py index 500787ab..5957a63d 100644 --- a/src/data/write_init_files.py +++ b/src/data/write_init_files.py @@ -1119,12 +1119,12 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports, outfile.write("end if", 5) outfile.write("field_data_ptr(:,:,constituent_idx) = constituent_default_value", 5) outfile.write("if (masterproc) then", 5) - outfile.write("write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value", 6) + outfile.write("write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value", 6) outfile.write("end if", 5) outfile.write("else", 4) outfile.write("field_data_ptr(:,:,constituent_idx) = 0._kind_phys", 5) outfile.write("if (masterproc) then", 5) - outfile.write("write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.'", 6) + outfile.write("write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.'", 6) outfile.write("end if", 5) outfile.write("end if", 4) outfile.write("end if", 3) From 006f41214d7c264ed8a735163c38e09f4548d330 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Thu, 19 Sep 2024 23:27:46 -0600 Subject: [PATCH 04/11] fix unit tests --- test/unit/sample_files/write_init_files/physics_inputs_4D.F90 | 4 ++-- .../unit/sample_files/write_init_files/physics_inputs_bvd.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_cnst.F90 | 4 ++-- .../unit/sample_files/write_init_files/physics_inputs_ddt.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_ddt2.F90 | 4 ++-- .../write_init_files/physics_inputs_ddt_array.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_host_var.F90 | 4 ++-- test/unit/sample_files/write_init_files/physics_inputs_mf.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_no_horiz.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_noreq.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_param.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_protect.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_scalar.F90 | 4 ++-- .../sample_files/write_init_files/physics_inputs_simple.F90 | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 b/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 index fcb3802a..e8476971 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 b/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 index 5bf9cf29..976c8981 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 b/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 index 7c830ac2..dbd43ff8 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 index 1810ede6..126b459c 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 index ba66a2cf..90ccfb50 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 index dd7140bb..5aa6eead 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 b/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 index 484c4007..c63724fc 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 @@ -207,12 +207,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 b/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 index 73667769..862bdd95 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 @@ -211,12 +211,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 b/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 index c229e563..ae3fed69 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 b/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 index a1703efe..56327041 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 @@ -203,12 +203,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_param.F90 b/test/unit/sample_files/write_init_files/physics_inputs_param.F90 index ab098ff6..2052b72b 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_param.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_param.F90 @@ -213,12 +213,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 b/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 index d0395c3a..91eeaf8b 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 b/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 index 07ca4c12..9b1333f7 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 b/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 index 37e8cb6f..e0473e59 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 @@ -210,12 +210,12 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia end if field_data_ptr(:,:,constituent_idx) = constituent_default_value if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' initialized to default value: ', constituent_default_value + write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else field_data_ptr(:,:,constituent_idx) = 0._kind_phys if (masterproc) then - write(iulog,*) 'Constituent ', trim(ccpp_required_data(req_idx)), ' default value not configured. Setting to 0.' + write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if end if end if From dc7b04a9d6c56c66e457892e1efc365c2cacba6b Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Wed, 25 Sep 2024 14:32:31 -0600 Subject: [PATCH 05/11] fix air composition standard names; add more water species to registry --- src/data/air_composition.F90 | 6 +++--- src/data/registry.xml | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/data/air_composition.F90 b/src/data/air_composition.F90 index f202ae97..e84fc837 100644 --- a/src/data/air_composition.F90 +++ b/src/data/air_composition.F90 @@ -346,8 +346,8 @@ subroutine air_composition_init() ! ! CLDICE ! - case('cloud_ice_water_mixing_ratio_wrt_moist_air_and_condensed_water') - call air_species_info('cloud_ice_water_mixing_ratio_wrt_moist_air_and_condensed_water', & + case('cloud_ice_mixing_ratio_wrt_moist_air_and_condensed_water') + call air_species_info('cloud_ice_mixing_ratio_wrt_moist_air_and_condensed_water', & ix, mw) thermodynamic_active_species_idx(icnst) = ix thermodynamic_active_species_cp (icnst) = cpice @@ -408,7 +408,7 @@ subroutine air_composition_init() ! ! GRAUQM ! - case('graupel_water_mixing_ratio_wrt_moist_air_and_conedensed_water') + case('graupel_water_mixing_ratio_wrt_moist_air_and_condensed_water') call air_species_info('graupel_water_mixing_ratio_wrt_moist_air_and_condensed_water', & ix, mw) thermodynamic_active_species_idx(icnst) = ix diff --git a/src/data/registry.xml b/src/data/registry.xml index 57a9ae3b..e22dabf5 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -406,5 +406,17 @@ rain mass mixing ratio with respect to moist air plus all airborne condensates RAINQM cnst_RAINQM + + snow mass mixing ratio with respect to moist air plus all airborne condensates + SNOWQM cnst_SNOWQM + + + graupel mass mixing ratio with respect to moist air plus all airborne condensates + GRAUQM cnst_GRAUQM + From afca8e23e4faa42f3fac7aa9a5ef2891699ac32c Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Wed, 6 Nov 2024 17:21:08 -0700 Subject: [PATCH 06/11] update externals; update cam_autogen to look for test schemes --- .gitmodules | 6 +++--- ccpp_framework | 2 +- cime_config/cam_autogen.py | 3 ++- src/physics/ncar_ccpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitmodules b/.gitmodules index 107bf2fd..03ef07e5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "ccpp-framework"] path = ccpp_framework url = https://github.com/NCAR/ccpp-framework - fxtag = 2024-10-31-dev + fxtag = 2024-11-05-dev fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/NCAR/ccpp-framework [submodule "history"] @@ -19,8 +19,8 @@ fxDONOTUSEurl = https://github.com/MPAS-Dev/MPAS-Model.git [submodule "ncar-physics"] path = src/physics/ncar_ccpp - url = https://github.com/ESCOMP/atmospheric_physics - fxtag = e95c172d7a5a0ebf054f420b08416228e211baa3 + url = https://github.com/peverwhee/atmospheric_physics + fxtag = ac5f740bcf0cd152bff1afae110ca4db05331bdb fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "ccs_config"] diff --git a/ccpp_framework b/ccpp_framework index 76dbf36d..bcc3abaa 160000 --- a/ccpp_framework +++ b/ccpp_framework @@ -1 +1 @@ -Subproject commit 76dbf36ddccbe1cf04fa9de04b38338c26b648aa +Subproject commit bcc3abaa4878e95b00f1b577c150cef7482bb506 diff --git a/cime_config/cam_autogen.py b/cime_config/cam_autogen.py index 929fac18..e08b1f5b 100644 --- a/cime_config/cam_autogen.py +++ b/cime_config/cam_autogen.py @@ -444,7 +444,8 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, suite_search = [source_mods_dir, atm_suites_path, atm_test_suites_path] # Find all scheme metadata files, organized by scheme name atm_schemes_path = os.path.join(atm_phys_top_dir, "schemes") - source_search = [source_mods_dir, atm_schemes_path] + atm_test_schemes_path = os.path.join(atm_phys_top_dir, "test", "test_schemes") + source_search = [source_mods_dir, atm_schemes_path, atm_test_schemes_path] all_scheme_files = _find_metadata_files(source_search, find_scheme_names) # Find the SDFs specified for this model build diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index e95c172d..7313bea5 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit e95c172d7a5a0ebf054f420b08416228e211baa3 +Subproject commit 7313bea5dd8f2580491362b0ed365f69eaa3b2c8 From 52e336d080b9e6489aeec1832614180b88123b52 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Wed, 6 Nov 2024 17:40:31 -0700 Subject: [PATCH 07/11] address reviewer comments --- src/data/write_init_files.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/data/write_init_files.py b/src/data/write_init_files.py index 5957a63d..c6352de0 100644 --- a/src/data/write_init_files.py +++ b/src/data/write_init_files.py @@ -573,6 +573,7 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, #Write line to file: outfile.write(log_arr_str, 2) # end for + arr_suffix = ', &' for var_num, var_name in enumerate(registry_constituents): # If at the end of the list, then update suffix: if var_num == num_input_vars-len(host_vars)-1: @@ -612,6 +613,7 @@ def write_ic_arrays(outfile, ic_name_dict, ic_max_len, #Write line to file: outfile.write(log_arr_str, 2) # end for + arr_suffix = ', &' for var_num, varname in enumerate(registry_constituents): #If at the end of the list, then update suffix: if var_num == num_input_vars-len(host_vars)-1: @@ -938,6 +940,7 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports, 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("real(kind=kind_phys) :: constituent_min_value", 2) outfile.write("integer :: constituent_errflg", 2) outfile.write("character(len=512) :: constituent_errmsg", 2) outfile.write("logical :: constituent_has_default", 2) @@ -1122,7 +1125,9 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports, outfile.write("write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value", 6) outfile.write("end if", 5) outfile.write("else", 4) - outfile.write("field_data_ptr(:,:,constituent_idx) = 0._kind_phys", 5) + outfile.comment("Intialize to constituent's configured minimum value", 5) + outfile.write("call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg)", 5) + outfile.write("field_data_ptr(:,:,constituent_idx) = constituent_min_value", 5) outfile.write("if (masterproc) then", 5) outfile.write("write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.'", 6) outfile.write("end if", 5) From 9ec57b43a70f51bf6bafb08ca68f4d480cd41b55 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Thu, 7 Nov 2024 14:04:20 -0700 Subject: [PATCH 08/11] update framework tag --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 03ef07e5..a0cac092 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "ccpp-framework"] path = ccpp_framework url = https://github.com/NCAR/ccpp-framework - fxtag = 2024-11-05-dev + fxtag = 2024-11-07-dev fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/NCAR/ccpp-framework [submodule "history"] From c04acead867f23743b775a80063bb61ca741637e Mon Sep 17 00:00:00 2001 From: peverwhee Date: Mon, 2 Dec 2024 11:22:15 -0700 Subject: [PATCH 09/11] update atmos phys hash --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index a0cac092..b6984f0f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,8 +19,8 @@ fxDONOTUSEurl = https://github.com/MPAS-Dev/MPAS-Model.git [submodule "ncar-physics"] path = src/physics/ncar_ccpp - url = https://github.com/peverwhee/atmospheric_physics - fxtag = ac5f740bcf0cd152bff1afae110ca4db05331bdb + url = https://github.com/ESCOMP/atmospheric_physics + fxtag = d46bb55e233e8f16b4e7a7b5a90352e99c7a5d72 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "ccs_config"] From bdb2906b72dda2dd4cb2b76684225d1d7ac8efb0 Mon Sep 17 00:00:00 2001 From: peverwhee Date: Mon, 2 Dec 2024 11:23:11 -0700 Subject: [PATCH 10/11] update submodules --- ccpp_framework | 2 +- src/physics/ncar_ccpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ccpp_framework b/ccpp_framework index bcc3abaa..27d0486f 160000 --- a/ccpp_framework +++ b/ccpp_framework @@ -1 +1 @@ -Subproject commit bcc3abaa4878e95b00f1b577c150cef7482bb506 +Subproject commit 27d0486f61e86d54921edc82139884e5f9c67700 diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index 7313bea5..29c7663a 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit 7313bea5dd8f2580491362b0ed365f69eaa3b2c8 +Subproject commit 29c7663a68d9b66bfe7926a56a595dbcbf2c385c From 092c2637681397cf590018793119170594fe609e Mon Sep 17 00:00:00 2001 From: peverwhee Date: Mon, 2 Dec 2024 12:57:47 -0700 Subject: [PATCH 11/11] fix unit tests --- .../unit/sample_files/write_init_files/physics_inputs_4D.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_bvd.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_cnst.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_ddt.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_ddt2.F90 | 5 ++++- .../write_init_files/physics_inputs_ddt_array.F90 | 5 ++++- .../write_init_files/physics_inputs_host_var.F90 | 5 ++++- .../unit/sample_files/write_init_files/physics_inputs_mf.F90 | 5 ++++- .../write_init_files/physics_inputs_no_horiz.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_noreq.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_param.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_protect.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_scalar.F90 | 5 ++++- .../sample_files/write_init_files/physics_inputs_simple.F90 | 5 ++++- 14 files changed, 56 insertions(+), 14 deletions(-) diff --git a/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 b/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 index e8476971..250179c8 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_4D.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 b/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 index 976c8981..99fa3c3d 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_bvd.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 b/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 index dbd43ff8..218d7f48 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_cnst.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 index 126b459c..d5675487 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 index 90ccfb50..57ea3c19 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt2.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 b/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 index 5aa6eead..c9c0b278 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_ddt_array.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 b/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 index c63724fc..9b4dc702 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_host_var.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -210,7 +211,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 b/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 index 862bdd95..7ccaf7ee 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_mf.F90 @@ -75,6 +75,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -214,7 +215,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 b/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 index ae3fed69..d238768e 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_no_horiz.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 b/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 index 56327041..52eb8cf9 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_noreq.F90 @@ -73,6 +73,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -206,7 +207,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_param.F90 b/test/unit/sample_files/write_init_files/physics_inputs_param.F90 index 2052b72b..3cdfb21a 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_param.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_param.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -216,7 +217,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 b/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 index 91eeaf8b..c578c2fc 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_protect.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 b/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 index 9b1333f7..4159f127 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_scalar.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if diff --git a/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 b/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 index e0473e59..1b55d8a3 100644 --- a/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 +++ b/test/unit/sample_files/write_init_files/physics_inputs_simple.F90 @@ -74,6 +74,7 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia ! 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 + real(kind=kind_phys) :: constituent_min_value integer :: constituent_errflg character(len=512) :: constituent_errmsg logical :: constituent_has_default @@ -213,7 +214,9 @@ subroutine physics_read_data(file, suite_names, timestep, read_initialized_varia write(iulog,*) 'Constituent ', trim(std_name), ' initialized to default value: ', constituent_default_value end if else - field_data_ptr(:,:,constituent_idx) = 0._kind_phys + ! Intialize to constituent's configured minimum value + call const_props(constituent_idx)%minimum(constituent_min_value, constituent_errflg, constituent_errmsg) + field_data_ptr(:,:,constituent_idx) = constituent_min_value if (masterproc) then write(iulog,*) 'Constituent ', trim(std_name), ' default value not configured. Setting to 0.' end if