Tuesday, October 8, 2013

Compiling MODFLOW with Code::Blocks and gfortran

While I wait for the US government to re-open, I have been working on a book about MODFLOW. One of the problems people can have when something goes wrong with MODFLOW is that it can be difficult to find the source of the problem. Often there is some obscure formatting problem that can be uncovered by running MODFLOW through a debugger. However, many users of MODFLOW don't have a FORTRAN compiler or a debugger and purchasing one is expensive. That is where Code::Blocks can be helpful. It is a free Integrated Development Environment (IDE) for, among other things, gfortran, a free fortran compiler and gdb, a free debugger. I tried it out and it seems to be an excellent program. I wish it were a little smarter about figuring out the best order in which to compile the source code files but that is my only complaint. The following instructions tell how to compile MODFLOW with Code::Blocks. I have also written up a brief description of using the debugger but I haven't included that here.



The first step is to install Code::Blocks and gfortran. Gfortran is included in “MinGW” which is included with the Windows installer for Code::Blocks. For other operating systems, you may need to install Gfortran separately. First go to http://www.codeblocks.org/downloads and click on the link for “Download the binary release.” Then choose the installer for your operating system. There are several different ones available. If you are on Windows, you will need MinGW so choose one of the installers that includes MinGW unless you already have MinGW installed. At the time this was written, the installer that you are most likely to be appropriate is “codeblocks-12.11mingw-setup.exe.” However, by the time you read this, there may be a more recent version.  Once the installer has downloaded, use the installer to install Code::Blocks.
Start Code::Blocks. It will display a dialog box asking whether you want associate C++ files with Code::Blocks. It is up to you how you wish to respond.
Next you will need to configure Code::Blocks to use gfortran.

1.     Select “Settings|Compiler.”
2.     Select the "GNU GCC Compiler", click the "Copy Button."

3.     Enter "GNU GFortran Compiler" as the name of the new compiler.

4.     Select the “Toolchain executables” tab and make sure the compiler’s installation directory is set correctly. Then set “gfortran.exe” as the C compiler, the C++ compiler and the linker for dynamic libs. Then Click OK to close the dialog box. 


If you have not already done so, download MODFLOW-2005 from the USGS web site (http://water.usgs.gov/nrp/gwsoftware/modflow2005/modflow2005.html‎). MODFLOW-2005 comes in a zip file that you will need to unzip. The directory to which it is normally unzipped is “C:\WRDAPP.” (WRDAPP stands for Water Resources Division Application.) On of the subdirectories include in the zip file is named “src.” It contains the source code for MODFLOW-2005. There are two subdirectories of the src directory that contain the source code for two other programs that are distributed with MODFLOW-2005. We won’t deal with those other programs.
Here are step-by-step instructions on compiling MODFLOW-2005.

1.     In Code::Blocks, select “File|New|Project” or click the “Create new project” link.

2.     Select “Fortran Application” and click the Go button.


3.     A new “wizard” dialog box will appear. If you have never used Code::Blocks before, the first page of the dialog box does nothing so just click the “Next” button.

4.     On the next page, specify a project title and a folder for MODFLOW-2005 and click the “Next” button. In this example, we will use “MF2005” as the name of the project. Code::Blocks will create a subfolder in that directory to contain the source code for the project. In this case, the folder is “C:\MF2005.”
 

5.     On the next page, be sure to set the compiler to the gfortran compiler and click the “Finish” button.


6.     At this point, the workspace will contain one file named “main.f95” under “Fortran Sources” that was automatically generated by Code::Blocks. That file isn’t needed because we already have all of the source code for MODFLOW. Click on it to select it. Then right-click and select “Remove file from project” from the pop-up menu. You may also delete the file from your computer using Windows Explorer.

7.     Copy all the source code files into the folder for the project (C:\MF2005).

8.     Right-click on “MF2005” and select “Add files…” from the pop-up menu.

9.     Select all the files in the folder for the project except MF2005.cbp, nogmg.txt, and openspec.inc. That should be all the files with the extension “.f”, “.f90”, “.c”, or “.h”.  (MF2005.cbp is the Code::Blocks project file. Nogmg.txt is used to replace gmg.f if MODFLOW is being compiled without the GMG package. Openspec.inc is part of the source code that will be “included” in several different source code files.)

10.  Code::Blocks will display a dialog box asking to which targets the files should belong. The default is that the files should belong to both the debug and release targets which is what we want so just click OK.



11.  Select Project|Build Options and select the “Compiler Settings” tab. Under that select the “defines” tab. Enter _UF on that tab.





12.  Switch to the Linker settings tab and click the “Add” button under “Link libraries”. Select the file libgfortran.a which you may find at C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.7.1\. When it asks if you want to “Keep this as a relative path?”, click the Yes button. Click the Add button two more times and select libgcc.a and libquadmath.a too.


13.  Because of dependencies among the various source code files in MODFLOW, the order in which they are compiled is important with gfortran. (With other compilers, it may not be necessary to specify a compile order.) The order in which the files are compiled can be controlled using the “priority weight” for each file. The default priority weight is 50. We will need to specify smaller priority weights for some files in order to control the order in which the files are compiled. The table below gives the priority weights that will be assigned. To assign a priority weight, expand “Fortran Sources” and right click on one of the files. From the pop-up menu, select “Properties”. In the dialog box, select the “Build” tab and use the slider to set the priority weight.


File name
Priority Weight
gwf2bas7.f
20
gwf2bcf7.f
25
gwf2huf7.f
22
gwf2ibs7.f
25
gwf2lak7.f
27
gwf2lpf7.f
22
gwf2str7.f
27
gwf2sub7.f
30
gwfsfrmodule.f
21
gwfuzfmodule.f
22
pcg7.f
30
pcgn2.f90
33
pcgn_solve2.f90
30
sip7.f
27

14.  Open Openspec.inc in a text editor such as Notepad. Openspec.inc has some Fortran code that used in opening binary files. What we want to do is to compile MODFLOW in such a way that a binary file is a “unstructured non-formatted” file so that programs that aren’t compiled with gfortran will be able to read them. With gfortran we need to change Openspec.inc slightly so that the binary files are unstructured non-formatted files.

15.  In FORTRAN, if the first character of a line is a “C”, that line is considered a comment and is ignored by the compiler. Note that most of the lines in openspec.inc are comments. There are only four lines that are not comments. The first one declares three variables named ACCESS,FORM, and ACTION. The other three lines each set one of those variables. If you look at the comments, for FORM, and ACTION, there are two versions of the lines that set those variables. For each of them, one version of the line is marked with a C as the first character and so is ignored by the compiler. The other one isn’t marked with a C as the first character and so is used by the compiler. In the version of MODFLOW with which I am working, the version of the line for ACTION is the “Standard FORTRAN” version. Leave it alone. The active version of the line for FORM is “Non-standard Fortran”. We will need to change that to the “Standard FORTRAN” version. Delete the “C” at the beginning of the line
C      DATA FORM/'UNFORMATTED'/
and insert a “C” at the beginning of the line
      DATA FORM/'BINARY'/

16.  Now both FORM and ACCESS are using Standard FORTRAN. We need to make two more changes. Locate the line where ACCESS is specified. It reads
      DATA ACCESS/'SEQUENTIAL'/
Insert a “C” at the beginning of that line so that it is ignored by the compiler. Then insert the following lines
C
c    Non-standard Fortran that causes code compiled by gfortran
C    on personal computers to use unstructured non-formatted
C    files.  This may make it possible for the non-formatted files used
C    by MODFLOW to be used with programs that are compiled by other
C    compilers.
C
      DATA ACCESS/'STREAM'/

17.  Select “Build|Build.”

1 comment:

  1. Hi Richard,

    This is a nice article but I'm getting a build error saying that "'Process terminated with status 1 (0 minute(s), 1 second(s))
    0 error(s), 30 warning(s) (0 minute(s), 1 second(s))"

    Do you have any idea about this error and could you please post the MODFLOW downloaded location?

    ReplyDelete