Skip to content

Commit

Permalink
feat: adds build option for compiling with different sets of constants (
Browse files Browse the repository at this point in the history
  • Loading branch information
bensonr authored Apr 6, 2022
1 parent 1f11d8f commit 16003bb
Show file tree
Hide file tree
Showing 11 changed files with 393 additions and 178 deletions.
1 change: 1 addition & 0 deletions CMAKE_INSTRUCTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ The following build options are available:
-D64BIT "Build 64-bit (r8) FMS library" DEFAULT: OFF
-DFPIC "Build with position independent code" DEFAULT: OFF
-DCONSTANTS "Build with <X> constants parameter definitions" DEFAULT:GFDL OPTIONS:GFS|GEOS|GFDL
-DINTERNAL_FILE_NML "Enable compiler definition -DINTERNAL_FILE_NML" DEFAULT: ON
-DENABLE_QUAD_PRECISION "Enable compiler definition -DENABLE_QUAD_PRECISION" DEFAULT: ON
-DGFS_PHYS "Enable compiler definition -DGFS_PHYS" DEFAULT:OFF
Expand Down
16 changes: 15 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,19 @@ if(HAVE_GETTID)
endif()

# Additional (optional) compiler definitions
if(NOT CONSTANTS)
set(CONSTANTS GFDL)
endif()
if(CONSTANTS STREQUAL "GFS")
list(APPEND fms_defs GFS_CONSTANTS)
elseif(CONSTANTS STREQUAL "GEOS")
list(APPEND fms_defs GEOS_CONSTANTS)
elseif(CONSTANTS STREQUAL "GFDL")
list(APPEND fms_defs GFDL_CONSTANTS)
else()
message(FATAL_ERROR "CONSTANTS=${CONSTANTS} option not supported")
endif()

if(GFS_PHYS)
list(APPEND fms_defs GFS_PHYS)
endif()
Expand Down Expand Up @@ -270,7 +283,8 @@ foreach(kind ${kinds})
target_include_directories(${libTgt}_f PRIVATE include
fms
fms2_io/include
mpp/include)
mpp/include
constants)
target_compile_definitions(${libTgt}_f PRIVATE "${fms_defs}")
target_compile_definitions(${libTgt}_f PRIVATE "${${kind}_defs}")

Expand Down
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ endif
# Make targets will be run in each subdirectory. Order is significant.
SUBDIRS = \
platform \
constants \
tridiagonal \
mpp \
constants \
memutils \
fms2_io \
mosaic2 \
Expand Down
13 changes: 9 additions & 4 deletions constants/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,20 @@ noinst_LTLIBRARIES = libconstants.la
# The convenience library depends on its source.
libconstants_la_SOURCES = \
fmsconstants.F90 \
gfdl_constants.h \
gfs_constants.h \
geos_constants.h \
constants.F90

fmsconstants.$(FC_MODEXT): constants_mod.$(FC_MODEXT)
FMSconstants.$(FC_MODEXT): gfdl_constants.h gfs_constants.h geos_constants.h
constants_mod.$(FC_MODEXT): fmsconstants.$(FC_MODEXT)

# Mod files are built and then installed as headers
MODFILES = \
constants_mod.$(FC_MODEXT) \
fmsconstants.$(FC_MODEXT)
fmsconstants.$(FC_MODEXT) \
constants_mod.$(FC_MODEXT)

nodist_include_HEADERS = $(MODFILES)
BUILT_SOURCES = $(MODFILES)
nodist_include_HEADERS = $(MODFILES)

include $(top_srcdir)/mkmods.mk
165 changes: 3 additions & 162 deletions constants/constants.F90
Original file line number Diff line number Diff line change
Expand Up @@ -18,175 +18,16 @@
!***********************************************************************
!> @defgroup constants_mod constants_mod
!> @ingroup constants
!> @brief Defines useful constants for Earth. Constants are defined as real
!! parameters. Constants are accessed through the "use" statement.
!> @author Bruce Wyman
!> @brief compatibility module as we transition to an FMSConstants module
!!
!> Constants have been declared as type REAL, PARAMETER.
!!
!! The value a constant can not be changed in a users program.
!! New constants can be defined in terms of values from the
!! constants module using a parameter statement.<br><br>
!!
!! The name given to a particular constant may be changed.<br><br>
!!
!! Constants can be used on the right side on an assignment statement
!! (their value can not be reassigned).
!!
!! Example:
!!
!! @verbatim
!! use constants_mod, only: TFREEZE, grav_new => GRAV
!! real, parameter :: grav_inv = 1.0 / grav_new
!! tempc(:,:,:) = tempk(:,:,:) - TFREEZE
!! geopotential(:,:) = height(:,:) * grav_new
!! @endverbatim

!> @file
!> @brief File for @ref constants_mod

!> @addtogroup constants_mod
!> @{
module constants_mod

!---variable for strong typing grid parameters
use platform_mod, only: r8_kind
implicit none
private

! Include variable "version" to be written to log file.
#include<file_version.h>
!-----------------------------------------------------------------------
! version is public so that write_version_number can be called for constants_mod
! by fms_init
public :: version

!! The small_fac parameter is used to alter the radius of the earth to allow one to
!! examine non-hydrostatic effects without the need to run full-earth high-resolution
!! simulations (<13km) that will tax hardware resources.
#ifdef SMALL_EARTH
#if defined(DCMIP) || (defined(HIWPP) && defined(SUPER_K))
real, public, parameter :: small_fac = 1._r8_kind / 120._r8_kind ! only needed for supercell test
#elif defined(HIWPP)
real, public, parameter :: small_fac = 1._r8_kind / 166.7_r8_kind
#else
real, public, parameter :: small_fac = 1._r8_kind / 10._r8_kind
#endif
#else
real, public, parameter :: small_fac = 1._r8_kind
#endif

#ifdef GFS_PHYS
! SJL: the following are from fv3_gfsphysics/gfs_physics/physics/physcons.f90
real, public, parameter :: RADIUS = 6.3712e+6_r8_kind * small_fac !< Radius of the Earth [m]
real(kind=r8_kind), public, parameter :: PI_8 = 3.1415926535897931_r8_kind !< Ratio of circle circumference
!! to diameter [N/A]
real, public, parameter :: PI = 3.1415926535897931_r8_kind !< Ratio of circle circumference
!! to diameter [N/A]
real, public, parameter :: OMEGA = 7.2921e-5_r8_kind / small_fac !< Rotation rate of the Earth [1/s]
real, public, parameter :: GRAV = 9.80665_r8_kind !< Acceleration due to gravity [m/s^2]
real(kind=r8_kind), public, parameter :: GRAV_8 = 9.80665_r8_kind !< Acceleration due to gravity
!! [m/s^2] (REAL(KIND=8))
real, public, parameter :: RDGAS = 287.05_r8_kind !< Gas constant for dry air [J/kg/deg]
real, public, parameter :: RVGAS = 461.50_r8_kind !< Gas constant for water vapor [J/kg/deg]
! Extra:
real, public, parameter :: HLV = 2.5e6_r8_kind !< Latent heat of evaporation [J/kg]
real, public, parameter :: HLF = 3.3358e5_r8_kind !< Latent heat of fusion [J/kg]
real, public, parameter :: con_cliq = 4.1855e+3_r8_kind !< spec heat H2O liq [J/kg/K]
real, public, parameter :: con_csol = 2.1060e+3_r8_kind !< spec heat H2O ice [J/kg/K]
real, public, parameter :: CP_AIR = 1004.6_r8_kind !< Specific heat capacity of dry
!! air at constant pressure [J/kg/deg]
real, public, parameter :: KAPPA = RDGAS/CP_AIR !< RDGAS / CP_AIR [dimensionless]
real, public, parameter :: TFREEZE = 273.15_r8_kind !< Freezing temperature of fresh water [K]

#else

real, public, parameter :: RADIUS = 6371.0e+3_r8_kind * small_fac !< Radius of the Earth [m]
real(kind=8), public, parameter :: PI_8 = 3.14159265358979323846_r8_kind !< Ratio of circle circumference
!! to diameter [N/A]
real, public, parameter :: PI = 3.14159265358979323846_r8_kind !< Ratio of circle circumference
!! to diameter [N/A]
real, public, parameter :: OMEGA = 7.292e-5_r8_kind / small_fac !< Rotation rate of the Earth [1/s]
real, public, parameter :: GRAV = 9.80_r8_kind !< Acceleration due to gravity [m/s^2]
real, public, parameter :: RDGAS = 287.04_r8_kind !< Gas constant for dry air [J/kg/deg]
real, public, parameter :: RVGAS = 461.50_r8_kind !< Gas constant for water vapor [J/kg/deg]
! Extra:
real, public, parameter :: HLV = 2.500e6_r8_kind !< Latent heat of evaporation [J/kg]
real, public, parameter :: HLF = 3.34e5_r8_kind !< Latent heat of fusion [J/kg]
real, public, parameter :: KAPPA = 2.0_r8_kind/7.0_r8_kind !< RDGAS / CP_AIR [dimensionless]
real, public, parameter :: CP_AIR = RDGAS/KAPPA !< Specific heat capacity of dry
!! air at constant pressure [J/kg/deg]
real, public, parameter :: TFREEZE = 273.16_r8_kind !< Freezing temperature of fresh water [K]
#endif

real, public, parameter :: STEFAN = 5.6734e-8_r8_kind !< Stefan-Boltzmann constant [W/m^2/deg^4]

real, public, parameter :: CP_VAPOR = 4.0_r8_kind*RVGAS !< Specific heat capacity of water vapor
!! at constant pressure [J/kg/deg]
real, public, parameter :: CP_OCEAN = 3989.24495292815_r8_kind !< Specific heat capacity taken from McDougall (2002)
!! "Potential Enthalpy ..." [J/kg/deg]
real, public, parameter :: RHO0 = 1.035e3_r8_kind !< Average density of sea water [kg/m^3]
real, public, parameter :: RHO0R = 1.0_r8_kind/RHO0 !< Reciprocal of average density of sea water [m^3/kg]
real, public, parameter :: RHO_CP = RHO0*CP_OCEAN !< (kg/m^3)*(cal/kg/deg C)(joules/cal) = (joules/m^3/deg
!! C) [J/m^3/deg]

real, public, parameter :: ES0 = 1.0_r8_kind !< Humidity factor. Controls the humidity content
!! of the atmosphere through
!! the Saturation Vapour Pressure expression
!! when using DO_SIMPLE. [dimensionless]
real, public, parameter :: DENS_H2O = 1000._r8_kind !< Density of liquid water [kg/m^3]
real, public, parameter :: HLS = HLV + HLF !< Latent heat of sublimation [J/kg]

real, public, parameter :: WTMAIR = 2.896440E+01_r8_kind !< Molecular weight of air [AMU]
real, public, parameter :: WTMH2O = WTMAIR*(RDGAS/RVGAS) !< Molecular weight of water [AMU]
real, public, parameter :: WTMOZONE = 47.99820_r8_kind !< Molecular weight of ozone [AMU]
real, public, parameter :: WTMC = 12.00000_r8_kind !< Molecular weight of carbon [AMU]
real, public, parameter :: WTMCO2 = 44.00995_r8_kind !< Molecular weight of carbon dioxide [AMU]
real, public, parameter :: WTMCH4 = 16.0425_r8_kind !< Molecular weight of methane [AMU]
real, public, parameter :: WTMO2 = 31.9988_r8_kind !< Molecular weight of molecular oxygen [AMU]
real, public, parameter :: WTMCFC11 = 137.3681_r8_kind !< Molecular weight of CFC-11 (CCl3F) [AMU]
real, public, parameter :: WTMCFC12 = 120.9135_r8_kind !< Molecular weight of CFC-21 (CCl2F2) [AMU]
real, public, parameter :: WTMN = 14.0067_r8_kind !< Molecular weight of Nitrogen [AMU]
real, public, parameter :: DIFFAC = 1.660000E+00_r8_kind !< Diffusivity factor [dimensionless]
real, public, parameter :: AVOGNO = 6.023000E+23_r8_kind !< Avogadro's number [atoms/mole]
real, public, parameter :: PSTD = 1.013250E+06_r8_kind !< Mean sea level pressure [dynes/cm^2]
real, public, parameter :: PSTD_MKS = 101325.0_r8_kind !< Mean sea level pressure [N/m^2]

real, public, parameter :: SECONDS_PER_DAY = 8.640000E+04_r8_kind !< Seconds in a day [s]
real, public, parameter :: SECONDS_PER_HOUR = 3600._r8_kind !< Seconds in an hour [s]
real, public, parameter :: SECONDS_PER_MINUTE = 60._r8_kind !< Seconds in a minute [s]
real, public, parameter :: RAD_TO_DEG = 180._r8_kind/PI !< Degrees per radian [deg/rad]
real, public, parameter :: DEG_TO_RAD = PI/180._r8_kind !< Radians per degree [rad/deg]
real, public, parameter :: RADIAN = RAD_TO_DEG !< Equal to RAD_TO_DEG for backward
!! compatability. [rad/deg]
real, public, parameter :: ALOGMIN = -50.0_r8_kind !< Minimum value allowed as argument
!! to log function [N/A]
real, public, parameter :: EPSLN = 1.0e-40_r8_kind !< A small number to prevent divide
!! by zero exceptions [N/A]

real, public, parameter :: RADCON = ((1.0E+02*GRAV)/(1.0E+04*CP_AIR))*SECONDS_PER_DAY !< Factor used
!! to convert flux divergence to
!! heating rate in degrees
!! per day [deg sec/(m day)]
real, public, parameter :: RADCON_MKS = (GRAV/CP_AIR)*SECONDS_PER_DAY !< Factor used to convert flux divergence to
!! heating rate in degrees
!! per day [deg sec/(m day)]
real, public, parameter :: O2MIXRAT = 2.0953E-01_r8_kind !< Mixing ratio of molecular oxygen in air [dimensionless]
real, public, parameter :: RHOAIR = 1.292269_r8_kind !< Reference atmospheric density [kg/m^3]
real, public, parameter :: VONKARM = 0.40_r8_kind !< Von Karman constant [dimensionless]
real, public, parameter :: C2DBARS = 1.e-4_r8_kind !< Converts rho*g*z (in mks) to dbars: 1dbar
!! = 10^4 (kg/m^3)(m/s^2)m [dbars]
real, public, parameter :: KELVIN = 273.15_r8_kind !< Degrees Kelvin at zero Celsius [K]

public :: constants_init
!> rename to not conflict with any other version vars
use FMSConstants, version => constants_version, constants_init => FMSconstants_init

contains

!> @brief dummy routine.
subroutine constants_init

end subroutine constants_init

end module constants_mod
!> @}
! close documentation grouping
82 changes: 76 additions & 6 deletions constants/fmsconstants.F90
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,87 @@
!* You should have received a copy of the GNU Lesser General Public
!* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
!***********************************************************************
!> @defgroup fmsconstants FMSconstants
!> @defgroup fmsconstants FMSConstants
!> @ingroup libfms
!> @brief Essentially a copy of @ref constants_mod for external usage alongside
!! @ref libfms.
!> @brief Defines useful constants for Earth. Constants are defined as real
!!
!> See @ref constants_mod for individual parameter information.
!> FMSconstants have been declared as REAL(kind=sizeof(rvar)), PARAMETER.
!!
!! The value of a constant defined and used from here cannot be changed
!! in a users program. New constants can be defined in terms of values
!! from the FMSconstants module and their includes using a parameter
!! statement.<br><br>
!!
!! The currently support contant systems are:
!! GFDL constants (gfdl_constants.h)
!! GEOS constants (geos_constants.h)
!! GFS constants (gfs_constants.h)
!! <br><br>
!!
!! The name given to a particular constant may be changed.<br><br>
!!
!! Constants can only be used on the right side on an assignment statement
!! (their value can not be reassigned).
!!
!! Example:
!!
!! @verbatim
!! use FMSConstants, only: TFREEZE, grav_new => GRAV
!! real, parameter :: grav_inv = 1.0 / grav_new
!! tempc(:,:,:) = tempk(:,:,:) - TFREEZE
!! geopotential(:,:) = height(:,:) * grav_new
!! @endverbatim
!> @file
!> @brief File for @ref FMSconstants_mod

!> @addtogroup FMSconstants_mod
!> @{
module FMSconstants

!> rename to not conflict with any other version vars
use constants_mod, version_constants => version
use platform_mod, only: r4_kind, r8_kind

!--- default scoping
implicit none

!--- needed with implicit none
real :: dum !< dummy real variable

#define RKIND sizeof(dum)

!--- set a default for the FMSConstants
#if !defined(GFDL_CONSTANTS) && !defined(GFS_CONSTANTS) && !defined(GEOS_CONSTANTS)
#define GFDL_CONSTANTS
#endif

!--- perform error checking and include the correct system of constants
#if defined(GFDL_CONSTANTS) && !defined(GFS_CONSTANTS) && !defined(GEOS_CONSTANTS)
#warning "Using GFDL constants"
#include <gfdl_constants.h>
#elif !defined(GFDL_CONSTANTS) && defined(GFS_CONSTANTS) && !defined(GEOS_CONSTANTS)
#warning "Using GFS constants"
#include <gfs_constants.h>
#elif !defined(GFDL_CONSTANTS) && !defined(GFS_CONSTANTS) && defined(GEOS_CONSTANTS)
#warning "Using GEOS constants"
#include <geos_constants.h>
#else
#error FATAL FMSConstants error - multiple constants macros are defined for FMS
#endif

!--- public interfaces
public :: FMSConstants_init

contains

!> @brief FMSconstants init routine
subroutine FMSconstants_init
use mpp_mod, only: stdlog
integer :: logunit
logunit = stdlog()

write (logunit,'(/,80("="),/(a))') trim(constants_version)

end subroutine FMSconstants_init

end module FMSconstants
!> @}
! close documentation grouping
Loading

0 comments on commit 16003bb

Please sign in to comment.