Build IWFM on Linux

The Integrated Water Flow Model (IWFM) is a water resources management and planning model that simulates groundwater, surface water, stream-groundwater interaction, and other components of the hydrologic system.

The model is written in Fortran, and windows executables for 32 and 64bit OS are readily available from their website. However for linux the code has to be compiled. In this post I’ll describe the tweaks needed to compile IWFM under Ubuntu. Using this process I have been able to compile IWFM on my desktop PC and a local installation on the UCDavis cluster.

Although the source code of the program is available it does not contain makefiles for linux builds. Yet the developers can provide upon request a linux version of the source code with all necessary files.

The code I received provided 2 makefiles for 32 and 64bit system. Here I’m explaining the installation of the 64bit version. The entry point of the installation is the file makeIWFM_3.02_x64.sh. 

We need first to change the path of the compilervars.sh on the second line. First do a search to find the location of the file using for example $ locate compilervars.sh and then change the path after source accordingly. The rest of the file is good to go. However we need few additional tweaks:

1) find the paths for the files ieee_exceptions.modintr and ieee_arithmetic.modintr.

2) The folders ../x64/Debug and ../x64/Release contain a makefile named makefile_objs_D and makefile_objs respectively. In these files there is an absolute definition of the location of the above files which is very unlikely that matches yours. Correct those paths accordingly

For the cluster installation we should load first the appropriate module. for example $ module load intel

Finally compile the code by running the $ ./makeIWFM_3.02_x64.sh

Note: The above steps worked for my desktop PC. However in the cluster I was getting warnings related to some ar flags that should be changed to xiar. In this case one need to modify the makefile under ../IWFM_UTIL/x64/Release and change the ar flag of the build library to xiar. It should read as

#### BUILD LIBRARY ####
IWFM_Util_x64.a : $(OBJS)
               xiar rc IWFM_Util_x64.a $(OBJS) 

 

How to align 2D shapes

Lets suppose that two shapes describe the same geographic area each digitized by different people at different coordinate system e.g. different transform, rotation and scaling and you want to match the two shapes.

This may seem unusual task. Unfortunately I had to deal with it. In particular I was given a Modflow model which was rotated and translated so that the left bottom corner of the domain was the (0,0) coordinate and I had to convert it to the coordinate system I was using. Also the two models described the same area, yet the digitization of the outline was made by different people therefore there were significantly different in the details.

The approach I took might not be the best and I welcome suggestions.

As I have some background in optimization I decided to run an optimization problem where the decision variables would be the translate, rotate and scale factors and the objective function would be the minimization of the area that remains after a Boolean subtraction between the two shapes.

Although this may sound a bit complicated task, it turned out to be relatively trivial using Matlab as it provides all the functionality one may need.

Lets name the outline of the modflow domain, modflow shape and the one with actual coordinates the target shape.

First we need to have the two shapes into Matlab workspace. For the modflow shape I rasterized the modflow grid and convert it to polygon shapefile in QGIS. The target shape was already a shapefile. The two shape files can be easily loaded with the shaperead matlab function:

 

coord_transf

It is quite important to have the two shapefiles somehow simplified otherwise the boolean operations might slow down the process.

Next we have to write the objective function. The arguments will be a vector 4×1 (X, Y, R S) i.e. x,y translation, rotation and scaling.

Create a new file, e.g. obj_fun.m and paste the code from this link:

Now we are ready to run the optimization problem. I have found that the pattern search is very reliable optimization algorithm for this problem.

First I run the optimization without scaling because small changes can make big differences. This will give an idea about the scaling limits.

 

first_try

The figure above shows the result of the first optimization. The red shape is the translated and rotated geometry. The translation and rotation looks good. But definitely we need scaling to make it better. We can also estimate that the scaling factor has to be greater than 1 and less than 1.5. Therefore we will set those values as constrains. In addition we will set the starting point of the next optimization run the solution of the previous run.

The figure below shows the final results of the optimization run

final_try

I should note that I had to perform quite a few optimization runs to reach this solution. In addition I performed few runs with fewer desicion variables. For example keep the rotation constant and optimize for scaling etc.

As you can see the result is not perfect and there are discrepancies especially in the north area. Therefore it may need to optimize for rotation.