Skip to content

Commit

Permalink
Update to OPS-LT v5.0.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
RIVM-OPS committed Sep 27, 2022
1 parent 65f5c92 commit ecd6d99
Show file tree
Hide file tree
Showing 322 changed files with 5,661 additions and 247 deletions.
137 changes: 137 additions & 0 deletions COMPILING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Compiling OPS

This is a short manual on how to compile the OPS model on a Linux machine.

## Dependencies

The following dependencies are required:

* Intel `ifort` Fortran compiler (RIVM uses version 2021.3.0 downloaded from [Intel oneAPI HPC](https://www.intel.com/content/www/us/en/developer/tools/oneapi/hpc-toolkit-download.html))
* CMake (RIVM uses version 3.18.2 downloaded from [cmake](https://cmake.org/download/))
* math77 library (RIVM uses Release 6 downloaded from [netlib](https://netlib.org/math/))
* pFUnit (RIVM uses [commit 594a6e2](https://github.com/Goddard-Fortran-Ecosystem/pFUnit/commit/594a6e2d26df70d45ead4392da65cdec69a0b869))

First, download and install/compile the above dependencies before proceeding.

## Compiling

After the dependencies are installed, OPS can be compiled using CMake. The OPS model is split into two parts (a library and an executable) that should be compiled separately.

### Specifying environment variables

The following environment variables need to be specified:

The build type. Choose from `Debug` or `Release`. The `Debug` version turns off optimizations and turns on tracebacks, warnings and debugging information.
Use the `Debug` version during development. The `Release` version results in an optimized executable, which should typically be used.
The specific compiler flags can be found in the `./ops_lib/CMakeLists.txt` and `./ops_lt/CMakeLists.txt` files.

```bash
export CMAKE_BUILD_TYPE="Release"
```

The location of the Math77 and pFUnit libraries. Example paths should be changed to the appropriate location on your system.

```bash
export MATHLIB_DIR="/home/user/MATH77/"
export PFUNIT_DIR="/home/user/pfunit/src/build/"
```

### Compiling the OPS library

First, change to the `ops_lib` folder and set its path as our `CMAKE_TOPDIR`:

```bash
cd ops_lib
export CMAKE_TOPDIR=`realpath .`
```

Create a `build` directory for cmake and change into it:
```bash
mkdir build
cd build
```

Next, we can compile the OPS library using CMake. First, we need to generate the necessary CMake files as follows:

```bash
cmake -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \
-DBIN_DIR="${CMAKE_TOPDIR}/bin" -DSRC_DIR="${CMAKE_TOPDIR}/src" \
-DMOD_DIR="${CMAKE_TOPDIR}/build/mod" \
-DTST_DIR="${CMAKE_TOPDIR}/tst" \
-DMOD_TST_DIR="${CMAKE_TOPDIR}/build/mod_tst" \
-DCOV_DIR="${CMAKE_TOPDIR}/build/codecov" \
-DMATHLIB_DIR="${MATHLIB_DIR}" \
-DPFUNIT_DIR="${PFUNIT_DIR}" "${CMAKE_TOPDIR}"
```

Then, we can build the library:

```bash
cmake --build .
```

In the final step, the library is installed into the `../bin` folder:

```bash
cmake --install .
```

Now, it is ready to be used by the main OPS executable. First, store the path of the `bin` folder:

```bash
export OPSLIB_DIR="${CMAKE_TOPDIR}/bin/"
```

Optionally, the unit tests can be run with:

```bash
cd ..
./bin/tst.exe
```

### Compiling the OPS executable

Then, change to the `ops_lt` folder and set its path as our `CMAKE_TOPDIR`:

```bash
cd "${CMAKE_TOPDIR}/../ops_lt"
export CMAKE_TOPDIR=`realpath .`
```

Create a `build` directory for cmake and change into it:
```bash
mkdir build
cd build
```

Next, we can compile the final OPS executable using CMake. First, we need to generate the necessary CMake files as follows:

```bash
cmake -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \
-DBIN_DIR="${CMAKE_TOPDIR}/bin" -DSRC_DIR="${CMAKE_TOPDIR}/src" \
-DMOD_DIR="${CMAKE_TOPDIR}/build/mod" \
-DTST_DIR="${CMAKE_TOPDIR}/tst" \
-DMOD_TST_DIR="${CMAKE_TOPDIR}/build/mod_tst" \
-DCOV_DIR="${CMAKE_TOPDIR}/build/codecov" \
-DOPSLIB_DIR="${OPSLIB_DIR}" -DMATHLIB_DIR="${MATHLIB_DIR}" \
-DPFUNIT_DIR="${PFUNIT_DIR}" "${CMAKE_TOPDIR}"
```

Then, we can build the executable:

```bash
cmake --build .
```

In the final step, the executable is installed into the `../bin` folder:

```bash
cmake --install .
```

Optionally, the unit tests can be run with:

```bash
cd ..
./bin/tst.exe
```
2 changes: 2 additions & 0 deletions ops_lib/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Set the default behavior for EOL conversion, in case people don't have core.autocrlf set.
* text=auto
56 changes: 56 additions & 0 deletions ops_lib/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# build directories
build
mod

# .F90 files at test directory (are generated by pFUnit)
tst/*.F90

# Generated sources
*__genmod.f90

# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

# Code coverage files (unit tests)
*.spi
*.spl
*.dyn
*.200
*.dpi
*.dpi.lock

# OPS output files
*.log

# vim
*.swp
67 changes: 67 additions & 0 deletions ops_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# CMake project file for OPS-Lib
cmake_minimum_required (VERSION 3.18)
project (ops_lib Fortran)
enable_language (Fortran)

# Add our local modules (.cmake files) to the module path
# Note: CMAKE_SOURCE_DIR is the top-level directory (where .git is located)
# CMAKE_MODULE_PATH specifies a search path for CMake modules to be loaded by include() or find_package()
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")

# Directories should be specified as command line arguments (e.g. -D BLD_DIR=./build)
# The following should be set:
# BLD_DIR, BIN_DIR, SRC_DIR, MOD_DIR, TST_DIR, MOD_TST_DIR, COV_DIR
# NETCDF_DIR, OPSLIB_DIR, MATHLIB_DIR, PFUNIT_DIR.

# make sure that the default build type is DEBUG
set ( CMAKE_CONFIGURATION_TYPES "Debug" "Release" "Coverage" )
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE DEBUG CACHE STRING
"Choose the type of build, options are: Debug, Release, Coverage."
FORCE)
endif (NOT CMAKE_BUILD_TYPE)
message (STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")

# append build type to output files
set(CMAKE_DEBUG_POSTFIX "_debug")
set(CMAKE_RELEASE_POSTFIX "_optim")
set(CMAKE_COVERAGE_POSTFIX "_cov")

# Get name of Fortran compiler (without directory):
get_filename_component (Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME)

# Compile flags depend on the compiler:
if (Fortran_COMPILER_NAME MATCHES "ifort.*")
# ifort (default/preferred compiler)
set (CMAKE_Fortran_FLAGS_RELEASE "-nowarn -DUNIX -fpp -assume byterecl -O2 -extend-source -module ${MOD_DIR}")
set (CMAKE_Fortran_FLAGS_DEBUG "-warn unused -diag-disable8291 -diag-disable7841 -DUNIX -fpp -assume byterecl -check -warn interfaces -debug-parameters all -traceback -O0 -g -extend-source -module ${MOD_DIR}")
set (CMAKE_Fortran_FLAGS_COVERAGE "${CMAKE_Fortran_FLAGS_DEBUG} -prof-gen=srcpos -prof-dir=${COV_DIR}")
else ()
message (STATUS "CMAKE_Fortran_COMPILER full path: " ${CMAKE_Fortran_COMPILER})
message (STATUS "Fortran compiler: " ${Fortran_COMPILER_NAME})
message (STATUS "No optimized Fortran compiler flags are known for compilers other than ifort, we just try -O2...")
set (CMAKE_Fortran_FLAGS_RELEASE "-O2")
set (CMAKE_Fortran_FLAGS_DEBUG "-O0 -g")
set (CMAKE_Fortran_FLAGS_COVERAGE "${CMAKE_Fortran_FLAGS_DEBUG} -prof-gen=srcpos -prof-dir=${COV_DIR}")
endif (Fortran_COMPILER_NAME MATCHES "ifort.*")

# Rerun CMake if the library paths change
set_property (DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/library_paths_config.txt")

# Double-check required library paths so we can give a clear error message
if ("${MATHLIB_DIR}" STREQUAL "")
message(FATAL_ERROR "MATHLIB_DIR should be set in ${CMAKE_SOURCE_DIR}/library_paths_config.txt")
endif()
if ("${PFUNIT_DIR}" STREQUAL "")
message(FATAL_ERROR "PFUNIT_DIR should be set in ${CMAKE_SOURCE_DIR}/library_paths_config.txt")
endif()

# Find math77 library
find_package (MATH77 REQUIRED)

# OPS lib source files in src, put output files in build/mod directory; then process CMakeLists.txt in src:
add_subdirectory(${SRC_DIR} ${MOD_DIR})

# OPS lib tst files (.pf) in tst, put output files in build/mod_tst directory; then process CMakeLists.txt in tst:
add_subdirectory(${TST_DIR} ${MOD_TST_DIR})

26 changes: 26 additions & 0 deletions ops_lib/cmake/FindMATH77.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# - Find MATH77 lib. Note that MATH77 has not been built with CMake.
include(FindPackageHandleStandardArgs)

# Find path for MATH77 library and if lib exists:
find_path(MATH77_INCLUDE_DIRS NAMES "libmath77_optim.a" PATHS "${MATHLIB_DIR}")
find_library(MATH77_LIBRARIES math77_optim PATHS "${MATHLIB_DIR}")

#message (" math include dir: ${MATH77_INCLUDE_DIRS}: ")
#message (" math lib: ${MATH77_LIBRARIES}: ")

# Set MATH77_FOUND; DEFAULT_MSG produces a standard error message if not found;
# report succes (first time only) if found :
find_package_handle_standard_args(MATH77
DEFAULT_MSG
MATH77_INCLUDE_DIRS
MATH77_LIBRARIES
)

# Set advanced state (for cmake-gui, so not necessary)
mark_as_advanced(MATH77_LIBRARIES MATH77_INCLUDE_DIRS)

# Set MATH77_LIBRARIES, MATH77_INCLUDE_DIRS; are used in other cmake scripts:
# if(MATH77_FOUND)
# set(MATH77_LIBRARIES ${MATH77_LIBRARY})
# set(MATH77_INCLUDE_DIRS ${MATH77_INCLUDE_DIR})
# endif()
23 changes: 23 additions & 0 deletions ops_lib/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# build OPS library

# Make a list of .f90 source files:
file(GLOB SRC_FILES *.f90)

# Define ops library (static)
add_library(ops STATIC ${SRC_FILES})

# Link MATH77 lib to ops lib:
target_link_libraries(ops PUBLIC ${MATH77_LIBRARIES})

# Set include directories to use when compiling target ops
target_include_directories(ops PUBLIC ${MATH77_INCLUDE_DIRS})

# After compilation, move .a (library archive) to ./bin
install(TARGETS ops DESTINATION ${BIN_DIR})

# After compilation, move .mod (module files) to ./bin/mod
# Trailing slash of MOD_DIR important, so that we can choose the name
# of the target directory
install(DIRECTORY "${MOD_DIR}/" DESTINATION "${BIN_DIR}/mod"
FILES_MATCHING PATTERN "*.mod" # include files matching *.mod
PATTERN "CMakeFiles" EXCLUDE) # exclude the CMakeFiles directory
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ MODULE m_commonconst_lib
INTEGER*4, PARAMETER :: NMETREG = 6 ! number of meteo regions

! CONSTANTS (dimensions of distributions, building effect table)
INTEGER*4, PARAMETER :: MAXDISTR = 9999 ! maximal number of distributions (for particle size or emission variation)
INTEGER*4, PARAMETER :: MAXDISTR = 999999 ! maximal number of distributions (for particle size or emission variation)
INTEGER*4, PARAMETER :: ncolBuildingEffectTable = 5 ! 1st column corresponds to distance from building. 2-5 correspond to different building types
!
! CONSTANTS - miscellaneous
Expand Down
14 changes: 8 additions & 6 deletions m_commonfile.f90 → ops_lib/src/m_commonfile.f90
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,19 @@ MODULE m_commonfile
CHARACTER*512 :: lufile ! name of file with land use data
CHARACTER*512 :: z0eurnam ! name of file with z0 values for Europe

CHARACTER*24 :: map_so2(5) ! name of file with background map SO2 (for 4 years)
CHARACTER*24 :: map_nox(5) ! name of file with background map NOx (for 4 years)
CHARACTER*24 :: map_nh3(5) ! name of file with background map NH3 (for 4 years)
CHARACTER*24 :: dir_chem_meteo(2) ! names of directories with chemical maps for actual (1) or prognosis (2) meteo
CHARACTER*24 :: map_so2(6) ! name of file with background map SO2 (for reference years)
CHARACTER*24 :: map_nox(6) ! name of file with background map NOx (for reference years)
CHARACTER*24 :: map_nh3(6) ! name of file with background map NH3 (for reference years)
CHARACTER*128 :: map_mass_prec ! filename with MASS_PREC averaged column mass precursor pre chemistry step, used for vchem
CHARACTER*128 :: map_mass_conv_dtfac ! filename with MASS_CONV_DTFAC = (100/dt) * averaged column mass converted in chemistry step, used for vchem
CHARACTER*128 :: map_no3_distr ! filename with distribution factors for different secondary species NO3
! HNO3/NO3_total, NO3_C/NO3_total, NO3_F/NO3_total

DATA map_so2 / 'bgso2c1984.ops', 'bgso2c1994.ops', 'bgso2c2005.ops', 'bgso2c2012.ops','bgso2c2020.ops' /
DATA map_nox / 'bgnoxc1984.ops', 'bgnoxc1994.ops', 'bgnoxc2005.ops', 'bgnoxc2012.ops','bgnoxc2020.ops' /
DATA map_nh3 / 'bgnh3c1984.ops', 'bgnh3c1994.ops', 'bgnh3c2005.ops', 'bgnh3c2012.ops','bgnh3c2020.ops' /
DATA dir_chem_meteo / 'Chem_meteo_actual', 'Chem_meteo_prognosis' /
DATA map_so2 / 'bgso2c1984.ops', 'bgso2c1994.ops', 'bgso2c2005.ops', 'bgso2c2012.ops','bgso2c2018.ops','bgso2cyyyy.ops' / ! yyyy = year (for years in the future
DATA map_nox / 'bgnoxc1984.ops', 'bgnoxc1994.ops', 'bgnoxc2005.ops', 'bgnoxc2012.ops','bgnoxc2018.ops','bgnoxcyyyy.ops' /
DATA map_nh3 / 'bgnh3c1984.ops', 'bgnh3c1994.ops', 'bgnh3c2005.ops', 'bgnh3c2012.ops','bgnh3c2018.ops','bgnh3cyyyy.ops' /
DATA map_mass_prec / 'xxx_mass_prec_yyyy.ops' / ! xxx = name primary species (SO2, NOx, NH3), yyyy = year (e.g. 2019)
DATA map_mass_conv_dtfac / 'xxx_mass_conv_dtfac_yyyy.ops' /
DATA map_no3_distr / 'no3_distr_yyyy.ops' /
Expand Down
3 changes: 1 addition & 2 deletions m_depac.f90 → ops_lib/src/m_depac.f90
Original file line number Diff line number Diff line change
Expand Up @@ -1634,8 +1634,7 @@ subroutine rc_temp_water(day_of_year,tk)
! = 286.1842 + 8.3445*sin(2*pi*(day_of_year - 113.5116*365/360)/365) =
! = 286.1842 + 8.3445*sin(2*pi*(day_of_year - 115.1)/365)

tk = 286.2 + 8.3*sin(day_of_year -113.5)
! tk = 286.2 + 8.34*sin(2*pi*(day_of_year - 115.1)/365)
tk = 286.2 + 8.34*sin(2*pi*(day_of_year - 115.1)/365)

end subroutine rc_temp_water

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit ecd6d99

Please sign in to comment.