diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c0eef4d..a4ff9319 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,23 @@ +# Set default project to unknown +if(NOT PROJECT) + message(STATUS "Setting CCPP project to 'unknown' as none was specified.") + set(PROJECT "Unknown") +endif (NOT PROJECT) + +#------------------------------------------------------------------------------ cmake_minimum_required(VERSION 2.8.11) +# Use rpaths on MacOSX +set(CMAKE_MACOSX_RPATH 1) + if(POLICY CMP0048) cmake_policy(SET CMP0048 NEW) - project(ccpp VERSION 0.1.0) + project(ccpp VERSION 1.0.0) else(POLICY CMP0048) project(ccpp) - set(PROJECT_VERSION 0.1.0) - set(PROJECT_VERSION_MAJOR 0) - set(PROJECT_VERSION_MINOR 1) + set(PROJECT_VERSION 1.0.0) + set(PROJECT_VERSION_MAJOR 1) + set(PROJECT_VERSION_MINOR 0) set(PROJECT_VERSION_PATCH 0) endif(POLICY CMP0048) @@ -21,19 +31,10 @@ enable_language(Fortran) #------------------------------------------------------------------------------ # Set package definitions -set(PACKAGE "CCPP") -set(AUTHORS "Timothy Brown" "David Gill" "Dom Heinzeller") +set(PACKAGE "ccpp-framework") +set(AUTHORS "Dom Heinzeller" "Timothy Brown" "David Gill") string(TIMESTAMP YEAR "%Y") -#------------------------------------------------------------------------------ -# The PGI compiler can not find any cap routines in their library. -# This is due to how it labels subroutines within a modules. -# For example the subroutine b() in the moduel a(), gets named a_b. -# GCC and Intel do NOT do this, it is name simply as b. -if ("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "PGI") - message(STATUS "WARNING: PGI compiler is not fully ISO_C compliant; working solution involves a hack pgifix.py") -endif() - #------------------------------------------------------------------------------ # CMake Modules # Set the CMake module path @@ -72,8 +73,16 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" - "MinSizeRel" "RelWithDebInfo") + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "Coverage") +endif() + +#------------------------------------------------------------------------------ +# The PGI compiler can not find any cap routines in their library. +# This is due to how it labels subroutines within a modules. +# For example the subroutine b() in the moduel a(), gets named a_b. +# GCC and Intel do NOT do this, it is name simply as b. +if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "PGI") + message(STATUS "WARNING: PGI compiler is not fully ISO_C compliant; working solution involves a hack pgifix.py") endif() #------------------------------------------------------------------------------ @@ -82,7 +91,7 @@ option(BUILD_SHARED_LIBS "Build a shared library" ON) #------------------------------------------------------------------------------ # Enable code coverage -if(CMAKE_COMPILER_IS_GNUCC AND (CMAKE_BUILD_TYPE STREQUAL "Coverage")) +if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU" AND (CMAKE_BUILD_TYPE STREQUAL "Coverage")) include(code_coverage) list(APPEND LIBS "gcov") endif() @@ -102,8 +111,8 @@ add_subdirectory(schemes) #------------------------------------------------------------------------------ # Configure and enable packaging -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Common Community Phyics Package") -set(CPACK_PACKAGE_VENDOR "DTC NCAR") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Common Community Physics Package - Framework") +set(CPACK_PACKAGE_VENDOR "GMTB NOAA/NCAR") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) @@ -115,7 +124,5 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") set(CPACK_SOURCE_GENERATOR "TBZ2") set(CPACK_GENERATOR "TBZ2") -#set(CPACK_GENERATOR "DEB") -#set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Timothy Brown") include(CPack) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index d77e0491..b5005ed9 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -23,9 +23,5 @@ if(BUILD_DOCUMENTATION) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM) - -# Define where to install the documentation - install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html - DESTINATION share/doc/${PROJECT_NAME}) endif() diff --git a/examples/suite_FV3_test.xml b/examples/suite_FV3_test.xml new file mode 100644 index 00000000..14ad4bce --- /dev/null +++ b/examples/suite_FV3_test.xml @@ -0,0 +1,11 @@ + + + + FV3_test_init + + + FV3_test_run + + + FV3_test_finalize + diff --git a/examples/suite_scm_GFS_test.xml b/examples/suite_scm_GFS_test.xml index f1fe8a71..14959224 100644 --- a/examples/suite_scm_GFS_test.xml +++ b/examples/suite_scm_GFS_test.xml @@ -1,6 +1,6 @@ - + GFS_initialize_scm_run diff --git a/schemes/CMakeLists.txt b/schemes/CMakeLists.txt index 41b39d94..c1443451 100644 --- a/schemes/CMakeLists.txt +++ b/schemes/CMakeLists.txt @@ -1,3 +1,9 @@ +# Set default project to unknown +if(NOT PROJECT) + message(STATUS "Setting CCPP project to 'unknown' as none was specified.") + set(PROJECT "Unknown") +endif (NOT PROJECT) + #------------------------------------------------------------------------------ # Add all the physics schemes in their own sub-directory (a.k.a repos) #------------------------------------------------------------------------------ @@ -16,6 +22,7 @@ ExternalProject_Add( INSTALL_COMMAND "" CMAKE_ARGS -DCCPP_INCLUDE_DIRS=${CCPP_INCLUDE_DIRS} -DCCPP_LIB_DIRS=${CCPP_LIB_DIRS} + -DPROJECT=${PROJECT} -DCCPP_MKCAP=${CMAKE_CURRENT_SOURCE_DIR}/mkcap.py -DCMAKE_Fortran_FLAGS=${CMAKE_Fortran_FLAGS} -DCMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS=${CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS} diff --git a/schemes/check/CMakeLists.txt b/schemes/check/CMakeLists.txt index 4a5d4b34..6a1502ff 100644 --- a/schemes/check/CMakeLists.txt +++ b/schemes/check/CMakeLists.txt @@ -1,6 +1,16 @@ +# Set default project to unknown +if(NOT PROJECT) + message(STATUS "Setting CCPP project to 'unknown' as none was specified.") + set(PROJECT "Unknown") +endif (NOT PROJECT) + # Use rpaths on MacOSX set(CMAKE_MACOSX_RPATH 1) +message (INFO "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") +message (INFO "CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}") +#message (FATAL_ERROR "BLA") + #------------------------------------------------------------------------------ cmake_minimum_required(VERSION 2.8.11) @@ -34,15 +44,23 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake") option(BUILD_SHARED_LIBS "Build a shared library" ON) #------------------------------------------------------------------------------ -# Add the CCPP include/module directory -set(CCPP_INCLUDE_DIRS "" CACHE FILEPATH "Path to ccpp includes") -set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES ${CCPP_INCLUDE_DIRS}) - -#------------------------------------------------------------------------------ -# Add the CCPP library -set(CCPP_LIB_DIRS "" CACHE FILEPATH "Path to ccpp library") -link_directories(${CCPP_LIB_DIRS}) -list(APPEND LIBS "ccpp") +# Add the CCPP include/module directory and libraries, currently depends on build +# see FV3_current_trunk/ccpp/CMakeLists.txt on how to set CCPP_INCLUDE_DIRS etc. +if (PROJECT MATCHES "CCPP-FV3") + # Add the CCPP include/module directory + set(CCPP_INCLUDE_DIRS "" CACHE FILEPATH "Path to ccpp includes") + set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES ${CCPP_INCLUDE_DIRS}) + # Add the CCPP library + set(CCPP_LIB_DIRS "" CACHE FILEPATH "Path to ccpp library") + link_directories(${CCPP_LIB_DIRS}) + list(APPEND LIBS "ccpp") +else (PROJECT MATCHES "CCPP-FV3") + # Add the CCPP include/module directory + INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/../../../../src") + # Add the CCPP library + LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/../../../../src") + list(APPEND LIBS "ccpp") +endif (PROJECT MATCHES "CCPP-FV3") #------------------------------------------------------------------------------ # Set the sources diff --git a/scripts/ccpp_prebuild.py b/scripts/ccpp_prebuild.py index 6072f4a9..688034e3 100755 --- a/scripts/ccpp_prebuild.py +++ b/scripts/ccpp_prebuild.py @@ -15,7 +15,7 @@ # Local modules from common import encode_container, execute from metadata_parser import merge_metadata_dicts, parse_scheme_tables, parse_variable_tables -from mkcap import Cap, CapsMakefile, SchemesMakefile +from mkcap import Cap, CapsMakefile, CapsCMakefile, SchemesMakefile, SchemesCMakefile from mkdoc import metadata_to_html, metadata_to_latex ############################################################################### @@ -23,7 +23,7 @@ ############################################################################### # List of configured host models -HOST_MODELS = ["FV3", "SCM"] +HOST_MODELS = ["FV3v0", "FV3v1", "SCM"] ############################################################################### # Set up the command line argument parser and other global variables # @@ -60,9 +60,12 @@ def import_config(host_model): # Definitions in host-model dependent CCPP prebuild config script config['variable_definition_files'] = ccpp_prebuild_config.VARIABLE_DEFINITION_FILES config['scheme_files'] = ccpp_prebuild_config.SCHEME_FILES + config['scheme_files_dependencies'] = ccpp_prebuild_config.SCHEME_FILES_DEPENDENCIES config['schemes_makefile'] = ccpp_prebuild_config.SCHEMES_MAKEFILE + config['schemes_cmakefile'] = ccpp_prebuild_config.SCHEMES_CMAKEFILE config['target_files'] = ccpp_prebuild_config.TARGET_FILES config['caps_makefile'] = ccpp_prebuild_config.CAPS_MAKEFILE + config['caps_cmakefile'] = ccpp_prebuild_config.CAPS_CMAKEFILE config['caps_dir'] = ccpp_prebuild_config.CAPS_DIR config['optional_arguments'] = ccpp_prebuild_config.OPTIONAL_ARGUMENTS config['module_include_file'] = ccpp_prebuild_config.MODULE_INCLUDE_FILE @@ -327,11 +330,13 @@ def generate_scheme_caps(metadata, arguments, caps_dir, module_use_template_sche os.chdir(BASEDIR) return (success, scheme_caps) -def generate_schemes_makefile(schemes, schemes_makefile): - logging.info('Generating schemes makefile snippet ...') +def generate_schemes_makefile(schemes, schemes_makefile, schemes_cmakefile): + logging.info('Generating schemes makefile/cmakefile snippet ...') success = True makefile = SchemesMakefile() makefile.filename = schemes_makefile + cmakefile = SchemesCMakefile() + cmakefile.filename = schemes_cmakefile # Adjust relative file path to schemes from caps makefile schemes_with_path = [] schemes_makefile_dir = os.path.split(os.path.abspath(schemes_makefile))[0] @@ -340,20 +345,26 @@ def generate_schemes_makefile(schemes, schemes_makefile): relative_path = './{0}'.format(os.path.relpath(scheme_filepath, schemes_makefile_dir)) schemes_with_path.append(os.path.join(relative_path, scheme_filename)) makefile.write(schemes_with_path) - logging.info('Added {0} schemes to makefile {1}'.format(len(schemes_with_path), makefile.filename)) + cmakefile.write(schemes_with_path) + logging.info('Added {0} schemes to makefile/cmakefile {1}/{2}'.format( + len(schemes_with_path), makefile.filename, cmakefile.filename)) return success -def generate_caps_makefile(caps, caps_makefile, caps_dir): - logging.info('Generating caps makefile snippet ...') +def generate_caps_makefile(caps, caps_makefile, caps_cmakefile, caps_dir): + logging.info('Generating caps makefile/cmakefile snippet ...') success = True makefile = CapsMakefile() makefile.filename = caps_makefile + cmakefile = CapsCMakefile() + cmakefile.filename = caps_cmakefile # Adjust relative file path to schemes from caps makefile caps_makefile_dir = os.path.split(os.path.abspath(caps_makefile))[0] relative_path = './{0}'.format(os.path.relpath(caps_dir, caps_makefile_dir)) caps_with_path = [ os.path.join(relative_path, cap) for cap in caps] makefile.write(caps_with_path) - logging.info('Added {0} auto-generated caps to makefile {1}'.format(len(caps_with_path), makefile.filename)) + cmakefile.write(caps_with_path) + logging.info('Added {0} auto-generated caps to makefile/cmakefile {1}/{2}'.format( + len(caps_with_path), makefile.filename, cmakefile.filename)) return success def main(): @@ -423,13 +434,14 @@ def main(): if not success: raise Exception('Call to generate_scheme_caps failed.') - # Add filenames of schemes to makefile - success = generate_schemes_makefile(config['scheme_files'], config['schemes_makefile']) + # Add filenames of schemes to makefile - add dependencies for schemes + success = generate_schemes_makefile(config['scheme_files_dependencies'] + config['scheme_files'], + config['schemes_makefile'], config['schemes_cmakefile']) if not success: raise Exception('Call to generate_schemes_makefile failed.') # Add filenames of scheme caps to makefile - success = generate_caps_makefile(scheme_caps, config['caps_makefile'], config['caps_dir']) + success = generate_caps_makefile(scheme_caps, config['caps_makefile'], config['caps_cmakefile'], config['caps_dir']) if not success: raise Exception('Call to generate_caps_makefile failed.') diff --git a/scripts/ccpp_prebuild_config_FV3.py b/scripts/ccpp_prebuild_config_FV3v0.py similarity index 93% rename from scripts/ccpp_prebuild_config_FV3.py rename to scripts/ccpp_prebuild_config_FV3v0.py index 072e20c8..34af9c5a 100755 --- a/scripts/ccpp_prebuild_config_FV3.py +++ b/scripts/ccpp_prebuild_config_FV3v0.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# CCPP prebuild config for GFDL Finite-Volume Cubed-Sphere Model (FV3) v0.0 +# CCPP prebuild config for GFDL Finite-Volume Cubed-Sphere Model (FV3) v0 ############################################################################### @@ -14,6 +14,11 @@ 'FV3/gfsphysics/physics/physcons.f90', ] +# Can be empty, since all physics schemes and their +# dependencies are hardcoded in the makefile in +# FV3/gfsphysics - will be fixed in FV3 v1 +SCHEME_FILES_DEPENDENCIES = [] + # Add all physics scheme files relative to basedir SCHEME_FILES = [ 'FV3/gfsphysics/physics/GFS_DCNV_generic.f90', @@ -22,7 +27,7 @@ 'FV3/gfsphysics/physics/GFS_PBL_generic.f90', 'FV3/gfsphysics/physics/GFS_SCNV_generic.f90', 'FV3/gfsphysics/physics/GFS_calpreciptype.f90', - 'FV3/gfsphysics/physics/GFS_debug.f90', + 'FV3/gfsphysics/physics/GFS_debug.F90', 'FV3/gfsphysics/physics/GFS_rrtmg_post.F90', 'FV3/gfsphysics/physics/GFS_rrtmg_pre.F90', 'FV3/gfsphysics/physics/GFS_stochastics.f90', @@ -55,8 +60,9 @@ 'FV3/gfsphysics/physics/sfc_sice.f', ] -# Auto-generated makefile snippet that contains all schemes +# Auto-generated makefile/cmakefile snippets that contain all schemes SCHEMES_MAKEFILE = 'FV3/gfsphysics/CCPP_SCHEMES.mk' +SCHEMES_CMAKEFILE = 'FV3/gfsphysics/CCPP_SCHEMES.cmake' # CCPP host cap in which to insert the ccpp_field_add statements; # determines the directory to place ccpp_{modules,fields}.inc @@ -64,8 +70,9 @@ 'FV3/gfsphysics/IPD_layer/IPD_CCPP_Driver.F90', ] -# Auto-generated makefile snippet that contains all caps +# Auto-generated makefile/cmakefile snippets that contain all caps CAPS_MAKEFILE = 'FV3/gfsphysics/CCPP_CAPS.mk' +CAPS_CMAKEFILE = 'FV3/gfsphysics/CCPP_CAPS.cmake' # Directory where to put all auto-generated physics caps CAPS_DIR = 'FV3/gfsphysics/physics' diff --git a/scripts/ccpp_prebuild_config_FV3v1.py b/scripts/ccpp_prebuild_config_FV3v1.py new file mode 100755 index 00000000..e56293d3 --- /dev/null +++ b/scripts/ccpp_prebuild_config_FV3v1.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python + +# CCPP prebuild config for GFDL Finite-Volume Cubed-Sphere Model (FV3) v1 + + +############################################################################### +# Definitions # +############################################################################### + +# DH* THIS ENTIRE BLOCK COMPILES, but remove for initial integration in FV3v1 +### # Add all files with metadata tables on the host model side, +### # relative to basedir = top-level directory of host model +### VARIABLE_DEFINITION_FILES = [ +### 'FV3/gfsphysics/GFS_layer/GFS_typedefs.F90', +### # DH* NEED TO CHANGE - THESE MUST BE IN FV3 CODEBASE, NOT IN CCPP! (DOES NOT APPLY TO PHYSCONS?) +### 'ccpp/physics/GFS_layer/GFS_typedefs.F90', +### # *DH +### 'ccpp/physics/physics/physcons.f90', +### ] +### +### # Add all physics scheme dependencies relative to basedir - note that these are all violations +### # of the CCPP requirement to not use any external modules except Fortran standard modules! +### SCHEME_FILES_DEPENDENCIES = [ +### 'ccpp/physics/physics/GFDL_parse_tracers.F90', +### 'ccpp/physics/physics/date_def.f', +### 'ccpp/physics/physics/funcphys.f90', +### 'ccpp/physics/physics/gfs_phy_tracer_config.f', +### 'ccpp/physics/physics/gocart_tracer_config_stub.f', +### 'ccpp/physics/physics/h2o_def.f', +### 'ccpp/physics/physics/iounitdef.f', +### 'ccpp/physics/physics/machine.F', +### 'ccpp/physics/physics/mersenne_twister.f', +### 'ccpp/physics/physics/mfpbl.f', +### 'ccpp/physics/physics/module_bfmicrophysics.f', +### 'ccpp/physics/physics/module_nst_model.f90', +### 'ccpp/physics/physics/module_nst_parameters.f90', +### 'ccpp/physics/physics/module_nst_water_prop.f90', +### 'ccpp/physics/physics/namelist_soilveg.f', +### 'ccpp/physics/physics/ozne_def.f', +### 'ccpp/physics/physics/physcons.f90', +### 'ccpp/physics/physics/physparam.f', +### 'ccpp/physics/physics/radcons.f90', +### 'ccpp/physics/physics/radiation_aerosols.f', +### 'ccpp/physics/physics/radiation_astronomy.f', +### 'ccpp/physics/physics/radiation_clouds.f', +### 'ccpp/physics/physics/radiation_gases.f', +### 'ccpp/physics/physics/radiation_surface.f', +### 'ccpp/physics/physics/radlw_datatb.f', +### 'ccpp/physics/physics/radlw_param.f', +### 'ccpp/physics/physics/radsw_datatb.f', +### 'ccpp/physics/physics/radsw_param.f', +### 'ccpp/physics/physics/rascnvv2.f', +### 'ccpp/physics/physics/sflx.f', +### 'ccpp/physics/physics/tridi.f', +### 'ccpp/physics/physics/wam_f107_kp_mod.f90', +### # DH* NEED TO CHANGE - THIS MUST BE IN FV3 CODEBASE, NOT IN CCPP! *DH +### #'FV3/gfsphysics/GFS_layer/GFS_typedefs.F90', +### 'ccpp/physics/GFS_layer/GFS_typedefs.F90', +### ] +### +### # Add all physics scheme files relative to basedir +### SCHEME_FILES = [ +### 'ccpp/physics/physics/FV3_test.F90', +### 'ccpp/physics/physics/GFS_DCNV_generic.f90', +### 'ccpp/physics/physics/GFS_MP_generic_post.f90', +### 'ccpp/physics/physics/GFS_MP_generic_pre.f90', +### 'ccpp/physics/physics/GFS_PBL_generic.f90', +### 'ccpp/physics/physics/GFS_SCNV_generic.f90', +### 'ccpp/physics/physics/GFS_calpreciptype.f90', +### 'ccpp/physics/physics/GFS_debug.F90', +### 'ccpp/physics/physics/GFS_rrtmg_post.F90', +### 'ccpp/physics/physics/GFS_rrtmg_pre.F90', +### 'ccpp/physics/physics/GFS_stochastics.f90', +### 'ccpp/physics/physics/GFS_suite_interstitial.ccpp.f90', +### 'ccpp/physics/physics/GFS_surface_generic.f90', +### 'ccpp/physics/physics/GFS_surface_loop_control.f', +### 'ccpp/physics/physics/GFS_zhao_carr_pre.f90', +### 'ccpp/physics/physics/cnvc90.f', +### 'ccpp/physics/physics/dcyc2.f', +### 'ccpp/physics/physics/get_prs_fv3.f90', +### 'ccpp/physics/physics/gscond.f', +### 'ccpp/physics/physics/gwdc.f', +### 'ccpp/physics/physics/gwdps.f', +### 'ccpp/physics/physics/mfdeepcnv.f', +### 'ccpp/physics/physics/mfshalcnv.f', +### 'ccpp/physics/physics/moninedmf.f', +### 'ccpp/physics/physics/ozphys.f', +### 'ccpp/physics/physics/precpd.f', +### 'ccpp/physics/physics/radlw_main.f', +### 'ccpp/physics/physics/radsw_main.f', +### 'ccpp/physics/physics/rayleigh_damp.f', +### 'ccpp/physics/physics/rrtmg_lw_post.F90', +### 'ccpp/physics/physics/rrtmg_lw_pre.F90', +### 'ccpp/physics/physics/rrtmg_sw_post.F90', +### 'ccpp/physics/physics/rrtmg_sw_pre.F90', +### 'ccpp/physics/physics/sfc_diag.f', +### 'ccpp/physics/physics/sfc_diff.f', +### 'ccpp/physics/physics/sfc_drv.f', +### 'ccpp/physics/physics/sfc_nst.f', +### 'ccpp/physics/physics/sfc_sice.f', +### ] + +# Add all files with metadata tables on the host model side, +# relative to basedir = top-level directory of host model +VARIABLE_DEFINITION_FILES = [ + 'FV3/gfsphysics/GFS_layer/GFS_typedefs.F90', + ] + +# Add all physics scheme dependencies relative to basedir - note that these are all violations +# of the CCPP requirement to not use any external modules except Fortran standard modules! +SCHEME_FILES_DEPENDENCIES = [ + 'ccpp/physics/physics/machine.F', + 'ccpp/physics/physics/radlw_param.f', + 'ccpp/physics/physics/radsw_param.f', + 'ccpp/physics/physics/physparam.f', + ] + +# Add all physics scheme files relative to basedir +SCHEME_FILES = [ + 'ccpp/physics/physics/FV3_test.F90', + ] +# *DH + +# Auto-generated makefile/cmakefile snippets that contain all schemes +SCHEMES_MAKEFILE = 'ccpp/physics/CCPP_SCHEMES.mk' +SCHEMES_CMAKEFILE = 'ccpp/physics/CCPP_SCHEMES.cmake' + +# CCPP host cap in which to insert the ccpp_field_add statements; +# determines the directory to place ccpp_{modules,fields}.inc +TARGET_FILES = [ + 'FV3/ipd/IPD_CCPP_Driver.F90', + #'ccpp/physics/physics/IPD_layer/IPD_CCPP_Driver.F90', + ] + +# Auto-generated makefile/cmakefile snippets that contain all caps +CAPS_MAKEFILE = 'ccpp/physics/CCPP_CAPS.mk' +CAPS_CMAKEFILE = 'ccpp/physics/CCPP_CAPS.cmake' + +# Directory where to put all auto-generated physics caps +CAPS_DIR = 'ccpp/physics/physics' + +# Optional arguments - only required for schemes that use +# optional arguments. ccpp_prebuild.py will throw an exception +# if it encounters a scheme subroutine with optional arguments +# if no entry is made here. Possible values are: 'all', 'none', +# or a list of standard_names: [ 'var1', 'var3' ]. +OPTIONAL_ARGUMENTS = { + 'rrtmg_sw' : { + 'rrtmg_sw_run' : [ + 'tendency_of_air_temperature_due_to_shortwave_heating_assuming_clear_sky_on_radiation_time_step', + 'components_of_surface_downward_shortwave_fluxes', + 'cloud_liquid_water_path', + 'mean_effective_radius_for_liquid_cloud', + 'cloud_ice_water_path', + 'mean_effective_radius_for_ice_cloud', + 'cloud_rain_water_path', + 'mean_effective_radius_for_rain_drop', + 'cloud_snow_water_path', + 'mean_effective_radius_for_snow_flake', + ], + }, + 'rrtmg_lw' : { + 'rrtmg_lw_run' : [ + 'tendency_of_air_temperature_due_to_longwave_heating_assuming_clear_sky_on_radiation_time_step', + 'cloud_liquid_water_path', + 'mean_effective_radius_for_liquid_cloud', + 'cloud_ice_water_path', + 'mean_effective_radius_for_ice_cloud', + 'cloud_rain_water_path', + 'mean_effective_radius_for_rain_drop', + 'cloud_snow_water_path', + 'mean_effective_radius_for_snow_flake', + ], + }, + #'subroutine_name_1' : 'all', + #'subroutine_name_2' : 'none', + #'subroutine_name_2' : [ 'var1', 'var3'], + } + +# Names of Fortran include files in the host model cap (do not change); +# both files will be written to the directory of each target file +MODULE_INCLUDE_FILE = 'ccpp_modules.inc' +FIELDS_INCLUDE_FILE = 'ccpp_fields.inc' + +# HTML document containing the model-defined CCPP variables +HTML_VARTABLE_FILE = 'ccpp/physics/CCPP_VARIABLES_FV3.html' + +# LaTeX document containing the provided vs requested CCPP variables +LATEX_VARTABLE_FILE = 'ccpp/framework/doc/DevelopersGuide/CCPP_VARIABLES_FV3.tex' + + +############################################################################### +# Template code to generate include files # +############################################################################### + +# Name of the CCPP data structure in the host model cap; +# in the case of FV3, this is a 2-dimensional array with +# the number of blocks as the first and the number of +# OpenMP threads as the second dimension; nb is the loop +# index for the current block, nt for the current thread +CCPP_DATA_STRUCTURE = 'cdata' + +# Modules to load for auto-generated ccpp_field_add code +# in the host model cap (e.g. error handling) +MODULE_USE_TEMPLATE_HOST_CAP = \ +''' +use ccpp_api, only: ccpp_error +''' + +## Modules to load for auto-generated ccpp_field_get code +## in the physics scheme cap (e.g. derived data types) +#MODULE_USE_TEMPLATE_SCHEME_CAP = \ +#''' +# use machine, only: kind_phys +# use module_radlw_parameters, only: sfcflw_type, topflw_type +# use module_radsw_parameters, only: cmpfsw_type, sfcfsw_type, topfsw_type +# use GFS_typedefs, only: GFS_statein_type, GFS_stateout_type, & +# GFS_sfcprop_type, GFS_coupling_type, & +# GFS_control_type, GFS_grid_type, & +# GFS_tbd_type, GFS_cldprop_type, & +# GFS_radtend_type, GFS_diag_type, & +# GFS_interstitial_type +#''' + +# Modules to load for auto-generated ccpp_field_get code +# in the physics scheme cap (e.g. derived data types) +MODULE_USE_TEMPLATE_SCHEME_CAP = \ +''' + use machine, only: kind_phys +''' \ No newline at end of file diff --git a/scripts/ccpp_prebuild_config_SCM.py b/scripts/ccpp_prebuild_config_SCM.py index 38bce749..16e9b3c5 100755 --- a/scripts/ccpp_prebuild_config_SCM.py +++ b/scripts/ccpp_prebuild_config_SCM.py @@ -14,6 +14,11 @@ 'scm/src/gmtb_scm_physical_constants.f90' ] +# Can be empty, since all physics schemes and their +# dependencies are hardcoded in CMakeLists in +# ccpp-physics - to fix, c.f. FV3 v1 +SCHEME_FILES_DEPENDENCIES = [] + # Add all physics scheme files relative to basedir SCHEME_FILES = [ 'ccpp-physics/GFS_layer/GFS_initialize_scm.F90', @@ -57,8 +62,9 @@ 'ccpp-physics/physics/sfc_sice.f', ] -# Auto-generated makefile snippet that contains all schemes +# Auto-generated makefile/cmakefile snippets that contain all schemes SCHEMES_MAKEFILE = 'ccpp-physics/CCPP_SCHEMES.mk' +SCHEMES_CMAKEFILE = 'ccpp-physics/CCPP_SCHEMES.cmake' # CCPP host cap in which to insert the ccpp_field_add statements; # determines the directory to place ccpp_{modules,fields}.inc @@ -66,8 +72,9 @@ 'scm/src/gmtb_scm.f90', ] -# Auto-generated makefile snippet that contains all caps +# Auto-generated makefile/cmakefile snippets that contain all caps CAPS_MAKEFILE = 'ccpp-physics/CCPP_CAPS.mk' +CAPS_CMAKEFILE = 'ccpp-physics/CCPP_CAPS.cmake' # Directory where to put all auto-generated physics caps CAPS_DIR = 'ccpp-physics/physics' diff --git a/scripts/mkcap.py b/scripts/mkcap.py index 2bab0d74..2a864a86 100755 --- a/scripts/mkcap.py +++ b/scripts/mkcap.py @@ -552,6 +552,48 @@ def filename(self): def filename(self, value): self._filename = value +class CapsCMakefile(object): + + header=''' +# All CCPP caps are defined here. +# +# This file is auto-generated using ccpp_prebuild.py +# at compile time, do not edit manually. +# +set(CAPS +''' + footer=''') +''' + + def __init__(self, **kwargs): + self._filename = 'sys.stdout' + for key, value in kwargs.items(): + setattr(self, "_"+key, value) + + def write(self, schemes): + if (self.filename is not sys.stdout): + f = open(self.filename, 'w') + else: + f = sys.stdout + + contents = self.header + for scheme in schemes: + contents += ' {0}\n'.format(scheme) + contents += self.footer + f.write(contents) + + if (f is not sys.stdout): + f.close() + + @property + def filename(self): + '''Get the filename of write the output to.''' + return self._filename + + @filename.setter + def filename(self, value): + self._filename = value + class SchemesMakefile(object): header=''' @@ -611,6 +653,48 @@ def filename(self): def filename(self, value): self._filename = value +class SchemesCMakefile(object): + + header=''' +# All CCPP schemes are defined here. +# +# This file is auto-generated using ccpp_prebuild.py +# at compile time, do not edit manually. +# +set(SCHEMES +''' + footer=''') +''' + + def __init__(self, **kwargs): + self._filename = 'sys.stdout' + for key, value in kwargs.items(): + setattr(self, "_"+key, value) + + def write(self, schemes): + if (self.filename is not sys.stdout): + f = open(self.filename, 'w') + else: + f = sys.stdout + + contents = self.header + for scheme in schemes: + contents += ' {0}\n'.format(scheme) + contents += self.footer + f.write(contents) + + if (f is not sys.stdout): + f.close() + + @property + def filename(self): + '''Get the filename of write the output to.''' + return self._filename + + @filename.setter + def filename(self, value): + self._filename = value + ############################################################################### if __name__ == "__main__": main() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 44608420..985709ad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,25 +1,38 @@ +# Set default project to unknown +if(NOT PROJECT) + message(STATUS "Setting CCPP project to 'unknown' as none was specified.") + set(PROJECT "Unknown") +endif (NOT PROJECT) + #------------------------------------------------------------------------------ # Set the sources -set(SOURCES - ccpp.F90 +set(SOURCES_C ccpp_dl.h ccpp_dl.c + ccpp_fields_idx.h + ccpp_fields_idx.c + ccpp_utils.h + ccpp_utils.c + ccpp_xml.h + ccpp_xml.c +) +set(SOURCES_F90 + ccpp.F90 ccpp_dl.F90 ccpp_errors.F90 ccpp_fcall.F90 ccpp_fields.F90 - ccpp_fields_idx.h - ccpp_fields_idx.c ccpp_strings.F90 ccpp_suite.F90 ccpp_types.F90 - ccpp_utils.h - ccpp_utils.c ccpp_xml.F90 - ccpp_xml.h - ccpp_xml.c ccpp_api.F90 ) +# Generate list of Fortran modules from defined sources +foreach(source_f90 ${SOURCES_F90}) + string(REGEX REPLACE ".F90" ".mod" module_f90 ${source_f90}) + list(APPEND MODULES_F90 ${CMAKE_CURRENT_BINARY_DIR}/${module_f90}) +endforeach() #------------------------------------------------------------------------------ # Find libXML2 @@ -87,11 +100,10 @@ add_subdirectory(tests) #------------------------------------------------------------------------------ # Define the executable and what to link -add_library(ccpp ${SOURCES}) +add_library(ccpp ${SOURCES_C} ${SOURCES_F90}) target_link_libraries(ccpp LINK_PUBLIC ${LIBS} ${CMAKE_DL_LIBS}) set_target_properties(ccpp PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} - COMPILE_FLAGS ${CMAKE_Fortran_FLAGS} LINK_FLAGS ${CMAKE_Fortran_FLAGS}) #------------------------------------------------------------------------------ @@ -99,15 +111,21 @@ set_target_properties(ccpp PROPERTIES VERSION ${PROJECT_VERSION} # # Find all the C headers and Fortran modules -file(GLOB headers +file(GLOB HEADERS_C "${CMAKE_CURRENT_SOURCE_DIR}/ccpp*.h" - "${CMAKE_CURRENT_BINARY_DIR}/ccpp*.mod" ) -target_include_directories(ccpp PUBLIC - $ - $ -) +if (PROJECT MATCHES "CCPP-FV3") + target_include_directories(ccpp PUBLIC + $ + $ + ) +else (PROJECT MATCHES "CCPP-FV3") + target_include_directories(ccpp PUBLIC + $ + $ + ) +endif (PROJECT MATCHES "CCPP-FV3") # Define where to install the library install(TARGETS ccpp @@ -123,6 +141,12 @@ install(EXPORT ccpp-targets DESTINATION lib/cmake ) -# Define where to install the modules -install(FILES ${headers} DESTINATION include/${PROJECT_NAME}) - +if (PROJECT MATCHES "CCPP-FV3") + # Define where to install the C headers and Fortran modules + install(FILES ${HEADERS_C} DESTINATION include) + install(FILES ${MODULES_F90} DESTINATION include) +else (PROJECT MATCHES "CCPP-FV3") + # Define where to install the C headers and Fortran modules + install(FILES ${HEADERS_C} DESTINATION include/${PROJECT_NAME}) + install(FILES ${MODULES_F90} DESTINATION include/${PROJECT_NAME}) +endif (PROJECT MATCHES "CCPP-FV3") diff --git a/src/ccpp.F90 b/src/ccpp.F90 index fb62f922..ef96ae18 100644 --- a/src/ccpp.F90 +++ b/src/ccpp.F90 @@ -32,7 +32,8 @@ module ccpp private public :: ccpp_init, & - ccpp_finalize + ccpp_finalize, & + ccpp_initialized contains @@ -51,7 +52,7 @@ subroutine ccpp_init(filename, cdata, ierr, suite) ierr = 0 - !call ccpp_debug('Called ccpp_init') + call ccpp_debug('Called ccpp_init') if (present(suite)) then cdata%suite = suite @@ -72,6 +73,9 @@ subroutine ccpp_init(filename, cdata, ierr, suite) return end if + ! Set flag indicating initialization state of cdata + cdata%initialized = .true. + end subroutine ccpp_init !> @@ -86,7 +90,7 @@ subroutine ccpp_finalize(cdata, ierr) ierr = 0 - !call ccpp_debug('Called ccpp_finalize') + call ccpp_debug('Called ccpp_finalize') ! Finalize the suite call ccpp_suite_finalize(cdata%suite, ierr) @@ -102,6 +106,25 @@ subroutine ccpp_finalize(cdata, ierr) return end if + ! Set flag indicating initialization state of cdata + cdata%initialized = .false. + end subroutine ccpp_finalize + !> + !! CCPP test initialization routine + !! + !! @param[in] cdata The ccpp_t type data + !! @return initialized .true. or .false. + ! + function ccpp_initialized(cdata) result(initialized) + type(ccpp_t), intent(in) :: cdata + logical :: initialized + + call ccpp_debug('Called ccpp_initialized') + + initialized = cdata%initialized + + end function ccpp_initialized + end module ccpp diff --git a/src/ccpp_api.F90 b/src/ccpp_api.F90 index 016f93c8..9c338121 100644 --- a/src/ccpp_api.F90 +++ b/src/ccpp_api.F90 @@ -23,7 +23,8 @@ module ccpp_api use ccpp_errors, only: ccpp_error, & ccpp_debug use ccpp, only: ccpp_init, & - ccpp_finalize + ccpp_finalize, & + ccpp_initialized use ccpp_fcall, only: ccpp_physics_init, & ccpp_physics_run, & ccpp_physics_finalize @@ -41,6 +42,7 @@ module ccpp_api ccpp_physics_init, & ccpp_physics_run, & ccpp_physics_finalize, & - ccpp_field_add + ccpp_field_add, & + ccpp_initialized end module ccpp_api diff --git a/src/ccpp_types.F90 b/src/ccpp_types.F90 index 9bcfdc94..b6a11c56 100644 --- a/src/ccpp_types.F90 +++ b/src/ccpp_types.F90 @@ -120,6 +120,7 @@ module ccpp_types type(c_ptr) :: fields_idx type(ccpp_field_t), allocatable, dimension(:) :: fields type(ccpp_suite_t) :: suite + logical :: initialized = .false. end type ccpp_t end module ccpp_types