Skip to content

Commit

Permalink
set up micm api test
Browse files Browse the repository at this point in the history
  • Loading branch information
boulderdaze committed Feb 3, 2024
1 parent 6622107 commit 8e5fb6e
Show file tree
Hide file tree
Showing 12 changed files with 351 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: build

on: [push, pull_request]

jobs:
build_test_connections:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: build Docker image
run: docker build -t musica -f docker/Dockerfile.musica .
- name: run tests in container
run: docker run --name test-container -t musica bash -c 'ctest'
31 changes: 31 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.21)

project(
atmosphericphysics
VERSION 0.0.0
LANGUAGES Fortran C CXX
)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH};${CMAKE_CURRENT_LIST_DIR}/cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_MODULE_PATH}/SetDefaults.cmake)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

# --------------------------------------------------------------------------------
# NOTE: If 'ENABLE_MICM_TEST' on, this is not a stand-alone cmake project anymore.
# MICM CCPP wrapper needs MUSICA library and ccpp-framework/src.
# To 'ENABLE_MICM_TEST', you either build a cmake project through
# 'docker/Dockerfile.musica' or follow the build instructions in the file.
# The following '$ENV' variables are set by the docker file.
# --------------------------------------------------------------------------------
option(ENABLE_MICM_TEST "Build the micm test" OFF)

if (ENABLE_MICM_TEST)
set(MUSICA_VERSION $ENV{MUSICA_VERSION})
set(MICM_SRC_PATH ${CMAKE_SOURCE_DIR}/musica/micm)
set(CCPP_SRC_PATH ${CMAKE_SOURCE_DIR}/$ENV{CCPP_SRC_PATH})
set(CCPP_TEST_SRC_PATH ${CMAKE_SOURCE_DIR}/test/include)

add_subdirectory(test/musica/micm)

enable_testing()
endif()
4 changes: 4 additions & 0 deletions cmake/SetDefaults.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Overwrite the init values choosen by CMake
if (CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_Fortran_FLAGS_DEBUG_INIT "-g")
endif()
5 changes: 5 additions & 0 deletions cmake/atmosphericphysicsConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@_Exports.cmake")

check_required_components("@PROJECT_NAME@")
37 changes: 37 additions & 0 deletions cmake/cmake_uninstall.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake

if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()

file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()

set(uninstall_dirs "@INSTALL_PREFIX@;@cmake_config_install_location@")

foreach(dir IN LISTS uninstall_dirs)
message(STATUS "Uninstalling ${dir}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove_directory ${dir}"
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing ${dir}")
endif()
endforeach()
72 changes: 72 additions & 0 deletions docker/Dockerfile.musica
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
FROM ubuntu:22.04

RUN apt update \
&& apt -y install \
cmake \
cmake-curses-gui \
curl \
libcurl4-openssl-dev \
libhdf5-dev \
m4 \
nlohmann-json3-dev \
vim \
zlib1g-dev \
git \
lcov \
make \
libnetcdff-dev \
valgrind \
gcc \
gfortran \
g++ \
tree \
&& apt clean

ENV FC=gfortran
ENV FFLAGS="-I/usr/include/"

RUN curl -LO https://github.com/jacobwilliams/json-fortran/archive/8.2.0.tar.gz \
&& tar -zxvf 8.2.0.tar.gz \
&& cd json-fortran-8.2.0 \
&& mkdir build \
&& cd build \
&& cmake -D SKIP_DOC_GEN:BOOL=TRUE .. \
&& make install

ENV JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0"

# Install MUSICA (MUSICA-C)
RUN git clone --depth 1 https://github.com/NCAR/musica.git
RUN cd musica \
&& cmake \
-S . \
-B build \
-D USE_MUSICA=ON \
-D USE_MUSICA_FORTRAN=OFF \
-D MAKE_MUSICA_FORTRAN_INSTALLABLE=ON \
-D ENABLE_TESTS=OFF \
-D ENABLE_TUVX=OFF \
&& cd build \
&& make install -j 8

RUN ln -s /usr/local/musica-0.5.0/lib/libmusica.a /usr/local/lib/libmusica.a
ENV MUSICA_VERSION="0.5.0"

COPY . atmospheric_physics

RUN cd atmospheric_physics \
&& mkdir lib \
&& cd lib \
&& git clone -b add_const_interface --depth 1 https://github.com/peverwhee/ccpp-framework.git
ENV CCPP_SRC_PATH="lib/ccpp-framework/src"

RUN cd atmospheric_physics \
&& cmake -S. \
-B build \
-D ENABLE_MICM_TEST=ON \
&& cmake --build ./build

RUN cd atmospheric_physics \
&& cp -r test/musica/micm/configs/chapman ./build/chapman

WORKDIR atmospheric_physics/build
10 changes: 10 additions & 0 deletions test/include/ccpp_kinds.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module ccpp_kinds

use ISO_FORTRAN_ENV, only: kind_phys => REAL64

implicit none
private

public kind_phys

end module ccpp_kinds
54 changes: 54 additions & 0 deletions test/musica/micm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
find_package(PkgConfig REQUIRED)
pkg_check_modules(netcdff IMPORTED_TARGET REQUIRED netcdf-fortran)

find_package(musica ${MUSICA_VERSION} REQUIRED)
message(STATUS " MUSICA version ${MUSICA_VERSION}")

include(FetchContent)

FetchContent_Declare(musica
GIT_REPOSITORY https://github.com/NCAR/musica.git
GIT_TAG main
)

set(USE_MUSICA OFF)
set(USE_MUSICA_FORTRAN ON)
set(MAKE_MUSICA_FORTRAN_INSTALLABLE OFF)
set(ENABLE_TUVX OFF)
set(ENABLE_TESTS OFF)

FetchContent_MakeAvailable(musica)

# ---------------------------------------------------------
# Create a test for MICM CCPP wrapper
# ---------------------------------------------------------

add_executable(test_micm_api test_micm_api.F90)

target_sources(test_micm_api
PUBLIC
${MICM_SRC_PATH}/micm.F90
${CCPP_SRC_PATH}/ccpp_api.F90
${CCPP_SRC_PATH}/ccpp_constituent_prop_mod.F90
${CCPP_SRC_PATH}/ccpp_hash_table.F90
${CCPP_SRC_PATH}/ccpp_hashable.F90
${CCPP_SRC_PATH}/ccpp_types.F90
${CCPP_TEST_SRC_PATH}/ccpp_kinds.F90
)

target_link_libraries(test_micm_api
PRIVATE
musica::musica-fortran
)

set_target_properties(test_micm_api
PROPERTIES
LINKER_LANGUAGE Fortran)

include(CTest)

add_test(
NAME test_micm_api
COMMAND $<TARGET_FILE:test_micm_api>
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
File renamed without changes.
File renamed without changes.
File renamed without changes.
122 changes: 122 additions & 0 deletions test/musica/micm/test_micm_api.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
subroutine test_micm_ccpp_api()
use iso_c_binding
use micm
use ccpp_kinds, only: kind_phys
use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t
use ccpp_constituent_prop_mod, only: ccpp_constituent_properties_t

implicit none

real(kind_phys) :: time_step ! s
real(kind_phys), dimension(2,1) :: temperature ! K
real(kind_phys), dimension(2,1) :: pressure ! Pa
real(kind_phys), dimension(2,1) :: dry_air_density ! kg m-3
type(ccpp_constituent_prop_ptr_t), dimension(5) :: constituent_props_ptr
real(kind_phys), dimension(5) :: molar_mass_arr ! kg mol-1
real(kind_phys), dimension(2,1,5) :: constituents ! kg kg-1
integer :: iulog
integer :: errcode
character(len=512) :: errmsg

! local variables
type(ccpp_constituent_properties_t), dimension(5), target :: constituent_props
type(ccpp_constituent_properties_t), pointer :: const_prop
integer :: i

time_step = 60._kind_phys

temperature(1,1) = 206.6374207_kind_phys
temperature(2,1) = 206.6374207_kind_phys

pressure(1,1) = 6152.049805_kind_phys
pressure(2,1) = 6152.049805_kind_phys

dry_air_density(1,1) = 3.580_kind_phys
dry_air_density(2,1) = 3.580_kind_phys

molar_mass_arr = (/ 200._kind_phys, 200._kind_phys, 200._kind_phys, 200._kind_phys, 200._kind_phys /)

constituents(1,1,1:5) = (/ 0.75_kind_phys, 8.1e-6_kind_phys, 2.42e-17_kind_phys, &
1.15e-5_kind_phys, 6.61e-9_kind_phys /)
constituents(2,1,1:5) = (/ 0.75_kind_phys, 8.1e-6_kind_phys, 2.42e-17_kind_phys, &
1.15e-5_kind_phys, 6.61e-9_kind_phys /)

iulog = 6

call constituent_props(1)%instantiate( &
std_name="water_vapor_mixing_ratio", &
long_name="water_vapor_mixing_ratio", &
units="kg kg-1", &
default_value=0._kind_phys, &
vertical_dim="vertical_layer_dimension", &
advected=.true., &
molar_mass=molar_mass_arr(1), &
errcode=errcode, errmsg=errmsg)
call constituent_props(2)%instantiate( &
std_name="water_vapor_mixing_ratio_a", &
long_name="water_vapor_mixing_ratio", &
units="kg kg-1", &
default_value=0._kind_phys, &
vertical_dim="vertical_layer_dimension", &
advected=.true., &
molar_mass=molar_mass_arr(2), &
errcode=errcode, errmsg=errmsg)
call constituent_props(3)%instantiate( &
std_name="water_vapor_mixing_ratio_b", &
long_name="water_vapor_mixing_ratio", &
units="kg kg-1", &
default_value=0._kind_phys, &
vertical_dim="vertical_layer_dimension", &
advected=.true., &
molar_mass=molar_mass_arr(3), &
errcode=errcode, errmsg=errmsg)
call constituent_props(4)%instantiate( &
std_name="water_vapor_mixing_ratio_c", &
long_name="water_vapor_mixing_ratio", &
units="kg kg-1", &
default_value=0._kind_phys, &
vertical_dim="vertical_layer_dimension", &
advected=.true., &
molar_mass=molar_mass_arr(4), &
errcode=errcode, errmsg=errmsg)
call constituent_props(5)%instantiate( &
std_name="water_vapor_mixing_ratio_d", &
long_name="water_vapor_mixing_ratio", &
units="kg kg-1", &
default_value=0._kind_phys, &
vertical_dim="vertical_layer_dimension", &
advected=.true., &
molar_mass=molar_mass_arr(5), &
errcode=errcode, errmsg=errmsg)

do i = 1, 5
const_prop => constituent_props(i)
call constituent_props_ptr(i)%set(const_prop, errcode, errmsg)
end do

call micm_init("chapman", iulog, errcode, errmsg)

write(*,*) " -- Initial time_step", time_step
write(*,*) " -- Initial temp", temperature
write(*,*) " -- Initial pressure", pressure
write(*,*) " -- Initial concentrations", constituents

if (errcode == 0) then
call micm_run(time_step, temperature, pressure, dry_air_density, constituent_props_ptr, &
constituents, iulog, errcode, errmsg)

write(*,*) " -- After solving, conentrations", constituents
else
write(*,*) " -- Exiting due to the error in creating solver"
stop 3
endif

write(*,*) " -- Completed solving"
call micm_final(iulog, errcode, errmsg)

end subroutine test_micm_ccpp_api

program run_test_micm_ccpp
implicit none
call test_micm_ccpp_api()
end program

0 comments on commit 8e5fb6e

Please sign in to comment.