Commit 484a0983 authored by Robert Schweppe's avatar Robert Schweppe

Merge branch 'develop' into 'master'

Develop

See merge request !61
parents de7fa502 8ea4d4a7
0.6.4
\ No newline at end of file
......@@ -16,7 +16,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
......
# This cmake file is not meant to be edited for a special setup.
# For special setups use cache line files or command line options, as described a few
# lines ahead concerning module INDEPENDENT builds
cmake_minimum_required(VERSION 3.5)
project(MPR Fortran)
# common (default) options to cmake
# -DCMAKE_BUILD_TYPE=Release - compile in debug or release mode
# -DBUILD_TESTING=ON - whether to compile tests
# -DCMAKE_VERBOSE_MAKEFILE=OFF - see all the commands
# -DCMAKE_BUILD_MODULE_SYSTEM_INDEPENDENT=OFF - build the library INDEPENDENT of the module system,
# -DCMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX=64 - find extra library paths on some systems (eve.nag62)
# so the build in the build tree works even after a module purge
# automatically enables testing
include(CTest)
set(CMAKE_BUILD_MODULE_SYSTEM_INDEPENDENT OFF CACHE STRING "build the module INDEPENDENT of the module system, so the build in the build tree works even after a module purge")
# set compiling flags for debug and relese version
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
# https://www.mankier.com/1/gfortran#Options-Options_to_request_or_suppress_errors_and_warnings
# this is super detailed...
# set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -Og -g -Wall -Wextra -Warray-temporaries -Wconversion -Wrealloc-lhs-all -fimplicit-none -fbacktrace -fcheck=all -ffpe-trap=zero,overflow,underflow -finit-real=snan")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -Og -g -Wall -Wextra -fimplicit-none -fbacktrace -fcheck=all -ffpe-trap=zero,overflow,underflow -finit-real=snan")
set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -Ofast")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ffree-line-length-none")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -warn all -g -debug extended -traceback -fp-stack-check -O0 -check all -fstack-protector-all -fstack-security-check -fpe0")
set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -O3 -qoverride-limits")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -assume byterecl -fp-model=source -m64 -assume realloc_lhs")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES "NAG")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -g -nan -O0 -C=all -strict95 -ieee=stop")
# set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pedantic -Wall -W -O -g")
set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -O4 -ieee=full")
# set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpp -colour -unsharedf95 -ideclient")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES "PGI")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -C -c -g -traceback -O0")
set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -fast")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Mfree -mcmodel=medium")
endif()
# library module specific settings
add_subdirectory(./src)
add_subdirectory(./src_python)
# this command is able to create dependencies, compile and add the sources in the right order
set(EXECUTABLE_NAME "${CMAKE_PROJECT_NAME}_runner")
add_executable(${EXECUTABLE_NAME} ./src/main.f90)
target_link_libraries(${EXECUTABLE_NAME} PUBLIC mpr)
# ifort and gfortran need the flag -cpp to interpret definitions like -DMRM2MHM
# the nag compiler is not able to interpret the flag -cpp but can interpret these definitions anyway
# so we check whether the compiler is able to use the flag -cpp
# for that we need the module CheckFortranCompilerFlag
include(CheckFortranCompilerFlag)
CHECK_Fortran_COMPILER_FLAG("-cpp" CPP_FLAG)
# if the flag exists, we add it to the compilation flags
if (CPP_FLAG)
target_compile_options(${EXECUTABLE_NAME} PUBLIC "-cpp")
endif()
#----------------------------------
# Get version (semantic versioning)
# C.F. semver.org
#----------------------------------
file ( STRINGS "${CMAKE_SOURCE_DIR}/.VERSION" VERSION )
string( REPLACE "." ";" VERSION_LIST ${VERSION} )
list(GET VERSION_LIST 0 VERSION_MAJOR)
list(GET VERSION_LIST 1 VERSION_MINOR)
list(GET VERSION_LIST 2 VERSION_PATCH)
set(PROJECT_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
message ( STATUS "CMake build configuration for ${CMAKE_PROJECT_NAME} ${PROJECT_VERSION}" )
set_target_properties ( ${EXECUTABLE_NAME}
PROPERTIES
COMPILE_FLAGS "${CMAKE_Fortran_FLAGS}"
OUTPUT_NAME "${CMAKE_PROJECT_NAME}"
SOVERSION "${VERSION_MAJOR}.${VERSION_MINOR}"
VERSION "${VERSION}"
)
if (CMAKE_BUILD_MODULE_SYSTEM_INDEPENDENT)
set_target_properties ( ${EXECUTABLE_NAME}
PROPERTIES
INSTALL_RPATH "${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}"
BUILD_WITH_INSTALL_RPATH ON
)
endif()
------------------
Copyright(c) 2018,
Copyright(c) 2019,
Helmholtz-Zentrum fuer Umweltforschung GmbH - UFZ.
All rights reserved.
......@@ -11,8 +11,8 @@ Registered Office: Leipzig
Registration Office: Amtsgericht Leipzig
Trade Register: Nr. B 4703
Chairman of the Supervisory Board: MinDirig Wilfried Kraus
Scientific Director: Prof. Dr. Dr. h.c. Georg Teutsch
Administrative Director: Dr. Heike Grassmann
Scientific Director: Prof. Dr. Georg Teutsch
Administrative Director: Prof. Dr. Heike Graßmann
------------------
......
......@@ -94,7 +94,7 @@ SHELL = /bin/bash
#
# . is current directory, .. is parent directory
SRCPATH := src/ deps/lib/src # where are the source files; use test_??? to run a test directory
SRCPATH := src/ deps/lightweight_fortran_lib/src deps/flogging/src # where are the source files; use test_??? to run a test directory
PROGPATH := . # where shall be the executable
CONFIGPATH := make.config # where are the $(system).$(compiler) files
MAKEDPATH := $(CONFIGPATH) # where is the make.d.sh script
......@@ -186,7 +186,7 @@ static := shared
EXTRA_FCFLAGS :=
EXTRA_F90FLAGS := #-mismatch #-C=undefined
EXTRA_DEFINES := -DWRF_HYDRO -DUFZ -DHIDDEN -DHYDRO_D
EXTRA_INCLUDES :=
EXTRA_INCLUDES := -Ideps/flogging/include
EXTRA_LDFLAGS :=
EXTRA_LIBS :=
EXTRA_CFLAGS :=
......
# Multiscale parameter regionalization - MPR
- The current release is **[MPR 0.3](https://git.ufz.de/chs/MPR/tags/0.3)**.
- The current release is **[MPR 0.5](https://git.ufz.de/chs/MPR/tags/0.5)**.
- General information can be found on the [MPR website](http://www.ufz.de/index.php?en=40126).
**Please note:** The [GitLab repository](https://git.ufz.de/chs/MPR) grants read access to the code.
If you like to contribute to the code, please contact [mhm-admin@ufz.de](mailto:mhm-admin@ufz.de).
If you would like to contribute to the code, please contact [robert.schweppe@ufz.de](mailto:robert.schweppe@ufz.de).
## Cite us in your scientific work
TODO: add citation, once it is published
The code can be cited as:
The model code can be cited as:
- **MPR:**
* MPR: Schweppe et al. (2019) TODO
## Installation
Please see the original publication of the MPR framework in Samaniego et al. (2010) and Kumar et al. (2013):
Please see the file [DEPENDENCIES](docs/src/dependencies.md) for external software required to run MPR.
All Python libraries needed to run the pre-processor script ([f90nml](https://github.com/marshallward/f90nml))
and the documentation builder ([FORD](https://github.com/Fortran-FOSS-Programmers/ford/wiki/Dependencies))
are also available on the UFZ Eve Linux-Cluster when loading the module from
`/global/apps/chspython/virtualenvs/python-3.6.2/`.
* Samaniego L., R. Kumar, S. Attinger (2010): Multiscale parameter regionalization of a grid-based hydrologic model at the mesoscale. Water Resour. Res., 46,W05523, doi:10.1029/2008WR007327, http://onlinelibrary.wiley.com/doi/10.1029/2008WR007327/abstract
* Kumar, R., L. Samaniego, and S. Attinger (2013): Implications of distributed hydrologic model parameterization on water fluxes at multiple scales and locations, Water Resour. Res., 49, doi:10.1029/2012WR012195, http://onlinelibrary.wiley.com/doi/10.1029/2012WR012195/abstract
## Compilation
## Dependencies
The code is based on the Fortran90 standard and also uses many features from
the Fortran 2003 and 2008 standards. MPR is routinely tested with the following
compilers: gfortran versions 6.0, 7.3 and 8.1, nag 6.2 (>build 6214). We
hope to support ifortran version 18.0 from Intel soon (pending bug report).
On the UFZ Eve Linux Cluster, currently only the gfortran compiler 7.3 works.
Please see the file [DEPENDENCIES](docs/src/01_dependencies.md)
for external software required to run and compile MPR.
## Documentation
In the near future, the documentation will be hosted on a gitlab server of the UFZ (gitlab pages),
once the infrastructure is set up. Until then the documentation needs to be
built locally by running the tool [FORD](https://github.com/Fortran-FOSS-Programmers/ford):
built locally by running the Python tool [FORD](https://github.com/Fortran-FOSS-Programmers/ford):
`ford ./docs/MPR.md` and then view `./doc/index.html` in your browser.
## License
......@@ -53,17 +46,12 @@ with the UFZ CHS MPR preprocessor. The
complete GNU license text can also be found at
<http://www.gnu.org/licenses/>.
## Quick start
MPR uses a logging library [flogging](https://github.com/Exteris/flogging) that is licensed under a permissive license [MIT](deps/flogging/LICENSE) with: Copyright (c) 2016 Daan van Vugt
1. Compile MPR with the `make` command, which uses settings from [Makefile](Makefile).
2. Run MPR with our test configuration `./mpr`, which uses settings from [mhm.nml](./predefined_nmls/mpr_default.nml).
3. Explore the results in the [output file](./default_output.nc), e.g. by using the NetCDF viewer `ncview`.
MPR uses a remapping library [SCRIP](https://github.com/SCRIP-Project/SCRIP) that is licensed under a permissive license [MIT](deps/SCRIP/SCRIP/source/copyright) with: Copyright (c) 1997, 1998 the Regents of the University of California
@Bugs
## Quick start
With gFortran compiler:
- (version 8.0), an error is issued ("Fortran runtime error: Bad repeat count in item * of list input"), if
to_file keyword is not last in respective data_array block.
- (version 6.0-8.0), the file mpr_global_paramaters.nml raises an end-of-file-error.
Strangely, it works when adding another line with a backslash at the end of the file.
A guide to set up a minimal example can be found
[here](docs/src/02_configuration/index.md).
.fuse_hidden*
*.o
*.so
test
test_mpi
*.mod
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = https://github.com/gitporst/flogging.git
branch = mpr_compat
commit = 789047189a2e7cedd78272522cfeedc9f1163faa
parent = 3ea27226b2ee091e3009ce6002d5e5b31d1792ac
method = merge
cmdver = 0.4.0
Copyright (c) 2016 Daan van Vugt
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
# Builds flogging as a shared library
F90=.f90
OBJ=.o
LIB = libflogging.so
SRC = src
BUILD = $(SRC)
FC = mpif90
ifeq ($(FC),nagfor)
FLAGS = -fpp -colour -free -Iinclude -DNAG
LIB_FLAGS =
else
FLAGS = -fpic -O3 -cpp -ffree-line-length-none -Iinclude
LIB_FLAGS = -shared
endif
ifeq (USE_MPI,1)
FLAGS += -DUSE_MPI
endif
SOURCES = $(wildcard $(SRC)/*$(F90))
OBJS = $(patsubst $(SRC)/%$(F90), $(BUILD)/%$(OBJ), $(SOURCES))
$(LIB): $(OBJS)
$(FC) $(LIB_FLAGS) -o $(LIB) $(OBJS)
$(BUILD)/%$(OBJ): $(SRC)/%$(F90)
$(FC) $(FLAGS) -c $< -o $@
$(BUILD)/flogging.o: $(BUILD)/vt100.o
# Some test executables
#
test : src/flogging.f90 src/tests/test_flogging.f90 src/vt100.f90 include/flogging.h
$(FC) $(FLAGS) -Iinclude src/vt100.f90 src/flogging.f90 src/tests/test_flogging.f90 -o test
test_mpi : src/flogging.f90 src/tests/test_flogging.f90 src/vt100.f90 include/flogging.h
$(FC) $(FLAGS) -DUSE_MPI -Iinclude src/vt100.f90 src/flogging.f90 src/tests/test_flogging.f90 -o test_mpi
.PHONY: clean doc
clean:
@find . -name '*.o' -delete
@find . -name '*.mod' -delete
@find . -name '*.so' -delete
@rm -f test test_mpi
doc:
ford flogging.md
doc_deploy: doc
git subtree push --prefix doc origin gh-pages
# Flogging
This logging system aims to be simple to use, similar to existing write statements and therefore easy to implement in existing codes,
while providing some convenient extra features not present in fortran by default.
Usage is very simple:
```fortran
use flogging
```
To load the logging module and its utility functions.
To use the preprovided macros, include the header file and turn on the preprocessor by compiling with `-cpp`
```C
#include "flogging.h"
```
This macro defines the following functions:
```fortran
log_fatal(format)
log_error(format)
log_warn(format)
log_info(format)
log_debug(format)
log_trace(format)
log_root_fatal(format)
log_root_error(format)
log_root_warn(format)
log_root_info(format)
log_root_debug(format)
log_root_trace(format)
```
Where `format` is usually `*`, but can be adjusted to suit your needs. Remember to include a single `A` specifier for the log lead if you set it yourself.
The functions print a log message only if the level is greater than or equal to the current minimum loglevel.
The second functions include a check to print a log message only from the root MPI process, if compiled
with `USE_MPI`. If not compiled with `USE_MPI`, it works the same as the log function.
If you do not want to use the preprocessor macros, you can log like this.
```fortran
if (logp(LEVEL)) then
write(logu,FORMAT) trim(logl(LEVEL))//" ", "this is a log message"
endif
```
Note that it is not possible to use the filename and linenumber features then.
# Installation
You can compile `flogging.f90` and `vt100.f90` into a library `flogging.so` with `make`.
To compile with MPI support use
```bash
make USE_MPI=1
```
Then, place `libflogging.so` into your `LD_LIBRARY_PATH` and put `flogging.h` into your include path.
## Compilation flags
Compile your own code with
```
-DDISABLE_LOG_DEBUG
```
to remove any debug statements from your code. Note that you cannot use `-v` to get these back then.
By default any `log_trace` messages are not included in the executable. Compile with
```
-DENABLE_LOG_TRACE
```
to get these back. Note that you still need to use `-vv` (by default) to see the messages.
This is a good compilation flag to have in your debug build profile.
## Transitioning to flogging
You can change all of the messages in your application to the `log_info` level by
```bash
git sed 's/write ?(\*,\*)/log_info(*)/g'
```
You might need to split some lines, as the `__FILE__` and `__LINE__` macros require quite some space.
This can also be circumvented by compiling with `-ffree-line-length-none` or equivalent.
# Examples
```fortran
log_error(*) "this is an error"
log_warn(*) "this is a warning"
log_info(*) "here, have some info"
log_debug(*) "and this is a debug message"
```
outputs (without any compilation flags)
```
localhost test.f90:9 ERROR this is an error
localhost test.f90:10 WARN this is a warning
localhost test.f90:11 INFO here, have some info
```
(The leading space is a consequence of using the fortran * format specifier)
## Interface
The module `flogging` defines some subroutines you can use to alter it's behaviour:
```fortran
public :: log_set_output_hostname
public :: log_set_output_severity
public :: log_set_output_date
public :: log_set_time_only
public :: log_set_output_fileline
public :: log_set_skip_terminal_check
public :: log_set_disable_colors
public :: log_disable_cli_arguments
```
## Command-line flags
The logging module allows the following command-line flags, checked at the time of the first log output.
```
-v, --verbose Increase the logging verbosity
-q, --quiet Decrease the logging verbosity
--log-output-hostname Output the hostname in the log lead
--log-force-colors Force colors, even when outputting to a file
--log-no-colors Disable colors (overrides --log-force-colors)
--log-output-date Output the date in the log lead
--log-output-time Output the time in the log lead
```
### Argument parsing
By default, flogging parses the command-line arguments above on the first invocation of `log()`.
If you want to use your own argument parsing you can disable this behaviour by calling `log_disable_cli_arguments` before any output is logged.
## Output to a file
Logging is to stderr by default. Another output unit can be selected by setting
```fortran
logu = some_unit
```
This will probably not work well with MPI.
## Internals
The latest documentation can be found [here](http://exteris.github.io/flogging/).
The module defines a function defining whether or not to print this log message,
```fortran
logp(level)
```
where level is one of `LOG_FATAL`, `LOG_ERROR`, `LOG_WARN`, `LOG_INFO`, `LOG_DEBUG` or `LOG_TRACE`.
The logp function can also be used with MPI support, using an optional integer parameter `only_n` to return true
only if the level is sufficient and the MPI rank of the current thread is equal to `only_n`.
This can be used to print messages only from the root thread, to prevent log messages from being printed N times as shown below.
```fortran
logp(level,0)
```
## Contributing
Pull requests and comments are appreciated.
## TODO
- Argument parsing is quite flaky (try -qqqqqq and see what happens)
- Time and date output at the same time does not work yet
- Compilation flag to control argument parsing
- Log output to a different file per MPI process
- Multiple logging streams/outputs (this will be tricky)
project: flogging
project_github: https://github.com/exteris/flogging
summary: FLOGGING -- Fortran logging system with MPI support
author: Daan van Vugt
github: https://github.com/exteris
project_dir: ./src
output_dir: ./doc
docmark: <
docmark_alt: *
predocmark: >
predocmark_alt: #
graph: true
coloured_edges: true
This library provides a logging framework for Fortran 90 and up, with MPI support, vt100 colors, command-line arguments and more.
License
---------------
The bspline-fortran source code and related files and documentation are distributed under a permissive [license](https://github.com/exteris/flogging/blob/master/LICENSE) (MIT).
/* This code is governed by the MIT license. See LICENSE for details. */
/* The lines below have little spacing to ease the fortran line-length requirements */
/* Log level constants */
#define LOG_LEVEL_FATAL_DEF 1
#define LOG_LEVEL_ERROR_DEF 2