Scheduled Downtime
On Friday 21 April 2023 @ 5pm MT, this website will be down for maintenance and expected to return online the morning of 24 April 2023 at the latest

Compiling WRF with custom external libraries

This post was from a previous version of the WRF&MPAS-A Support Forum. New replies have been disabled and if you have follow up questions related to this post, then please start a new thread from the forum home page.


New member
I would like to compile WRF with a dynamically linked fortran machine learning library that would be called from one of the parameterization subroutines in the phys directory. Where in configure.wrf, a Makefile, or somewhere else should I add the path to the compiled library files so that they are linked during compilation?
This is a good one!

Most of the physics schemes in the WRF model are "modern fortran", in that they are inside of Fortran modules. There are certainly objects (parameters, functions, subroutines) that the top-level physics routines do not define within their scope, and those objects tends to come from other modules (via USE statements). Examples of this are physical constants. However, there are a collection of general purpose routines that are not put inside of modules (such as those myriad CALL wrf_error_fatal("blah") examples).

Do a simple example like the following (basically adding an extra subroutine to call from a physics scheme). Once you can do that, the next step is to make it a library.

I added a call to subroutine foo in the Thompson MP scheme. Here are the files I touched.

> git status -uno
# On branch pgi
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#	new file:   phys/foo.F
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#	modified:   main/depend.common
#	modified:   phys/Makefile
#	modified:   phys/module_mp_thompson.F

Here are the changes:

> git diff
diff --git a/main/depend.common b/main/depend.common
index 4b8f2f9..2b0483b 100644
--- a/main/depend.common
+++ b/main/depend.common
@@ -368,6 +368,7 @@ module_mp_milbrandt2mom.o : ../frame/module_wrf_error.o \
 module_mp_thompson.o : ../frame/module_wrf_error.o \
+               foo.o \
 module_mp_nssl_2mom.o : ../frame/module_wrf_error.o \
diff --git a/phys/Makefile b/phys/Makefile
index 1c3fc06..c5724c5 100644
--- a/phys/Makefile
+++ b/phys/Makefile
@@ -200,7 +200,8 @@ MODULES = \
        module_wind_fitch.o \
        module_sf_lake.o \
        module_diagnostics_driver.o \
-       module_irrigation.o
+       module_irrigation.o \
+       foo.o
         module_fr_fire_driver.o \
diff --git a/phys/module_mp_thompson.F b/phys/module_mp_thompson.F
index 596dcaa..441420a 100644
--- a/phys/module_mp_thompson.F
+++ b/phys/module_mp_thompson.F
@@ -944,6 +944,7 @@
       xmu_g = mu_g
       call radar_init
+      call foo
       if (.not. iiwarm) then
 !..Rain collecting graupel & graupel collecting rain.

Once this works for you, then turn your object file into a library file (something like libsome_name.a).
I always hit "Submit" instead of "Preview".

This lib file needs to go into WRF/main. You can build the lib file, assuming that you are in the phys directory, with:
ar ru ../main/libfoo.a foo.a

In the configure.wrf file, in the configure.wrf file, edit this line (it is likely blank after the "="):
LDFLAGS_LOCAL   =       -L$(WRF_SRC_ROOT_DIR)/main -lfoo

Once this builds and runs, then we are ready for the last step. You have demonstrated your ability to modify the build to get a simple lib used. Start with a clean repo (none of the above changes).

Add in the call to the interface routine from your library to the selected physics scheme. In the configure.wrf, in the "LIB" line, add in the location of your library and name:
LIB             =    $(LIB_BUNDLED) $(LIB_EXTERNAL) $(LIB_LOCAL) $(LIB_WRF_HYDRO)  $(NETCDF4_DEP_LIB) -Labsolute_path_to_lib_file -lFULL_LIB_FILE_NAME

For the -l option, instead of -llibname.a you could say -lname.