From aa501817547f9a3c0057a6ca8c4b4d0f43c82739 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 19 Oct 2020 12:18:16 -0400 Subject: [PATCH] add cmake build to Data Atmosphere --- CMakeLists.txt | 2 ++ DATM/CMakeLists.txt | 49 +++++++++++++++++++++++++++++++++++++++++++ DATM/datm.F90 | 50 ++++++++++++++++++++++---------------------- tools/CMakeLists.txt | 29 +++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 25 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 DATM/CMakeLists.txt create mode 100644 tools/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2b11964 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(tools) +add_subdirectory(DATM) diff --git a/DATM/CMakeLists.txt b/DATM/CMakeLists.txt new file mode 100644 index 0000000..dc53624 --- /dev/null +++ b/DATM/CMakeLists.txt @@ -0,0 +1,49 @@ +# Data-Atmosphere compiler flags +if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") + set(CMAKE_Fortran_FLAGS "-g -fbacktrace -ffree-line-length-none") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}") + set(CMAKE_Fortran_FLAGS_RELEASE "-O2") + set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -fcheck=bounds -ffpe-trap=invalid,zero,overflow,underflow" ) + set(CMAKE_Fortran_LINK_FLAGS "") +elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") + set(CMAKE_Fortran_FLAGS "-g -traceback") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O -assume realloc_lhs") + set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -debug minimal -fp-model precise") + set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -check -check noarg_temp_created -check nopointer -fpe0 -ftrapuv -link_mpi=dbg") + set(CMAKE_Fortran_LINK_FLAGS "") +else() + message(WARNING "Fortran compiler with ID ${CMAKE_Fortran_COMPILER_ID} will be used with CMake default options") +endif() + +#list(APPEND _datatm_defs_private coupled) + +add_library(datatm STATIC AtmBundleCreate.F90 + AtmFieldUtils.F90 + AtmForce.F90 + AtmGridUtils.F90 + AtmInternalFields.F90 + AtmModel.F90 + LocalDefs.F90 + datm.F90) + +set_target_properties(datatm PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mod) +target_include_directories(datatm PRIVATE $) +target_compile_definitions(datatm PUBLIC "${_datatm_defs_private}") +target_include_directories(datatm PUBLIC $ + $) +target_link_libraries(datatm PUBLIC esmf) + +############################################################################### +### Install +############################################################################### +install( + TARGETS datatm + EXPORT datatm-config + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + COMPONENT Library) + +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mod DESTINATION ${CMAKE_INSTALL_PREFIX}/DATM) + +install(EXPORT datatm-config + DESTINATION lib/cmake) diff --git a/DATM/datm.F90 b/DATM/datm.F90 index 836031d..66e0993 100644 --- a/DATM/datm.F90 +++ b/DATM/datm.F90 @@ -12,7 +12,7 @@ module DAtm model_routine_SS => SetServices, & model_label_SetRunClock => label_SetRunClock, & model_label_Advance => label_Advance - + ! Fields exported by Atm use AtmFieldUtils, only : AtmFieldsAdvertise, AtmFieldsRealize use AtmFieldUtils, only : AtmFieldDump @@ -25,9 +25,9 @@ module DAtm use AtmInternalFields implicit none - + private - + public SetServices type(ESMF_VM) :: vm @@ -41,20 +41,20 @@ module DAtm __FILE__ contains - + subroutine SetServices(model, rc) type(ESMF_GridComp) :: model integer, intent(out) :: rc - + rc = ESMF_SUCCESS - + ! the NUOPC model component will register the generic methods call NUOPC_CompDerive(model, model_routine_SS, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + ! set entry point for methods that require specific implementation - + ! overwrite the default IPDv00 with IPDv02 call ESMF_GridCompSetEntryPoint(model, & ESMF_METHOD_INITIALIZE, & @@ -75,7 +75,7 @@ subroutine SetServices(model, rc) phaseLabelList=(/"IPDv02p2"/), & userRoutine=InitializeP2, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + ! specialize label_SetRunClock which ensures the correct timeStep ! is set during the run cycle ! -> NUOPC specializes by default --->>> first need to remove the default @@ -101,7 +101,7 @@ subroutine SetServices(model, rc) call ESMF_VMGet(vm,petCount=petCnt,localPet=lPet,rc=rc) end subroutine SetServices - + !----------------------------------------------------------------------------- subroutine InitializeP0(model, importState, exportState, externalClock, rc) @@ -177,7 +177,7 @@ subroutine InitializeP0(model, importState, exportState, externalClock, rc) isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then - read(value, '(i)', iostat=iostat) scalar_field_count + read(value, *, iostat=iostat) scalar_field_count if (iostat /= 0) then call ESMF_LogSetError(ESMF_RC_ARG_BAD, & msg="DATM : ScalarFieldCount not an integer: "//trim(value), & @@ -193,7 +193,7 @@ subroutine InitializeP0(model, importState, exportState, externalClock, rc) isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then - read(value, '(i)', iostat=iostat) scalar_field_idx_grid_nx + read(value, *, iostat=iostat) scalar_field_idx_grid_nx if (iostat /= 0) then call ESMF_LogSetError(ESMF_RC_ARG_BAD, & msg="DATM : ScalarFieldIdxGridNX not an integer: "//trim(value), & @@ -209,7 +209,7 @@ subroutine InitializeP0(model, importState, exportState, externalClock, rc) isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then - read(value, '(i)', iostat=iostat) scalar_field_idx_grid_ny + read(value, *, iostat=iostat) scalar_field_idx_grid_ny if (iostat /= 0) then call ESMF_LogSetError(ESMF_RC_ARG_BAD, & msg="DATM : ScalarFieldIdxGridNY not an integer: "//trim(value), & @@ -228,13 +228,13 @@ end subroutine InitializeP0 !----------------------------------------------------------------------------- subroutine InitializeP1(model, importState, exportState, externalClock, rc) - + type(ESMF_GridComp) :: model type(ESMF_State) :: importState type(ESMF_State) :: exportState type(ESMF_Clock) :: externalClock integer, intent(out) :: rc - + ! local variables type(ESMF_Config) :: cf real(ESMF_KIND_R8) :: medAtmCouplingIntervalSec @@ -242,7 +242,7 @@ subroutine InitializeP1(model, importState, exportState, externalClock, rc) character(20) :: cvalue rc = ESMF_SUCCESS - + call ESMF_LogWrite("User initialize routine InitP1 Atm started", ESMF_LOGMSG_INFO) ! Set up the fields in the AtmBundle @@ -321,11 +321,11 @@ subroutine InitializeP1(model, importState, exportState, externalClock, rc) call ESMF_LogWrite("User initialize routine InitP1 Atm finished", ESMF_LOGMSG_INFO) end subroutine InitializeP1 - + !----------------------------------------------------------------------------- subroutine InitializeP2(model, importState, exportState, externalClock, rc) - + type(ESMF_GridComp) :: model type(ESMF_State) :: importState type(ESMF_State) :: exportState @@ -333,7 +333,7 @@ subroutine InitializeP2(model, importState, exportState, externalClock, rc) type(ESMF_Time) :: currTime type(ESMF_VM) :: vm integer, intent(out) :: rc - + ! local variables type(ESMF_Grid) :: gridIn type(ESMF_Grid) :: gridOut @@ -400,7 +400,7 @@ subroutine InitializeP2(model, importState, exportState, externalClock, rc) call AtmInit(model, exportState, externalClock, rc) - ! AtmInit calls AtmForce and loads the values for the first integration + ! AtmInit calls AtmForce and loads the values for the first integration ! timestep, so..... ! -> set Updated Field Attribute to "true", indicating to the IPDv02p5 ! generic code to set the timestamp for this Field @@ -417,7 +417,7 @@ subroutine InitializeP2(model, importState, exportState, externalClock, rc) call ESMF_LogWrite(trim(AtmBundleFields(ii)%shortname)//' set to Updated', ESMF_LOGMSG_INFO) enddo !ii - + ! set scalars for cmeps if(len_trim(scalar_field_name) > 0) then call State_SetScalar(dble(iatm),scalar_field_idx_grid_nx, exportState, localPet, & @@ -462,14 +462,14 @@ subroutine InitializeP2(model, importState, exportState, externalClock, rc) call ESMF_LogWrite("User initialize routine InitP2 Atm finished", ESMF_LOGMSG_INFO) end subroutine InitializeP2 - + !----------------------------------------------------------------------------- subroutine ModelAdvance(model, rc) type(ESMF_GridComp) :: model integer, intent(out) :: rc - + ! local variables type(ESMF_State) :: exportState type(ESMF_Clock) :: modelClock @@ -483,7 +483,7 @@ subroutine ModelAdvance(model, rc) character(len=ESMF_MAXSTR) :: export_timestr rc = ESMF_SUCCESS - + call ESMF_LogWrite("User routine ModelAdvance Atm started", ESMF_LOGMSG_INFO) ! query the Component for its clock and exportState @@ -493,7 +493,7 @@ subroutine ModelAdvance(model, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! HERE THE MODEL ADVANCES: currTime -> currTime + timeStep - + ! Because of the way that the internal Clock was set by default, ! its timeStep is equal to the parent timeStep. As a consequence the ! currTime + timeStep is equal to the stopTime of the internal Clock diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000..a0bdeec --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,29 @@ +list(APPEND _tools_srcs + GFS_diagnostics.F90 + cdf.F90 + charstrings.F90 + fieldmatch.F90 + find_t850.F90 + gfstonc_sfc.F90 + gfstonc_sig.F90 + kinds.F90 + param.F90 + rdnemsio.F90 + setup_outcdf.F90 + sfc2nc.F90 + sfcvars.F90 + sigma2nc.F90 + sigmavars.F90 + tm_secs_from_bc.F90 + write_sigmacdf.F90) + +add_executable(nemsio2nc ${_tools_srcs}) +set_target_properties(nemsio2nc PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mod) +target_include_directories(nemsio2nc PRIVATE $) +target_link_libraries(nemsio2nc PRIVATE nemsio::nemsio) +target_link_libraries(nemsio2nc PRIVATE w3nco::w3nco_d) +target_link_libraries(nemsio2nc PRIVATE NetCDF::NetCDF_Fortran) + +install(TARGETS nemsio2nc + RUNTIME DESTINATION bin + COMPONENT Utility)