A modified version of rayinvr that can work properly on modern Linux(e.g. Ubuntu 18.04) and Windows(e.g. Windows 10) platform.
On Linux, you need to install x11
library and gfortran
. For example, on Ubuntu 18.04:
sudo apt install gfortran libx11-dev
On Windows, you need to install GNU Make and mingw-w64 manually.
Assuming we are in root directory of rayinvr source now.
Inside each subdirectory there is a Makefile
to make two versions of each program. For example, you can build tramp
as the following steps:
cd tramp
make xtramp FC=gfortran CC=gcc
make tramp FC=gfortran CC=gcc
# or just `make FC=gfortran CC=gcc`, will build both the two versions.
PS: the keyword arguments FC=gfortran CC=gcc
means setting Fortran Compiler to gfortran
and C Compiler to gcc
. By default, the two variables are f77
and cc
respectively.
The first version, prefixed by the letter x
, is based on X11
graphics system. The second version is originally for users who have access to the commercial graphics package called Uniras. However, the second version would also be helpful if you just need to calculate without ploting. On Windows, there is no x11
library so that the second version is the only choice.
After this step, we will get rayinvr.exe
, tramp.exe
etc. under build
directory.
This step is optional.
Add build
directory to PATH
, then we will be able to run rayinvr
and other commands at any path.
In original rayinvr repository, Zelt provided 8 example datasets, which is helpful to test our build results.
But we can't run our commands on these datasets directly, because I have changed main.f
to handle higher float precision when reading v.in
file (see below). If you have tried running commands at examples
directory, you will probably end up with an error msg like this:
At line 236 of file main.f (unit = 20, file = 'v.in')
Fortran runtime error: Bad value during floating point read
Error termination. Backtrace:
But don't worry, I have made a python script which can convert old style v.in file into high precision version, and I have put all converted example datasets in examples-new
directory.
Now, let's try example3 (Why not example1? because example3 is neither too simple, nor too complicated):
# On Windows 10 WSL for my case
# go to dataset directory
cd examples-new/e3
# run rayinvr.exe
../../build/rayinvr.exe
The output will be as below, basically consistent with that of original rayinvr:
shot# 1: ray code 2.2: 59 rays traced
shot# 1: ray code 3.2: 60 rays traced
shot# -2: ray code 2.2: 17 rays traced
shot# -2: ray code 3.2: 7 rays traced
shot# 2: ray code 2.2: 63 rays traced
shot# 2: ray code 3.2: 73 rays traced
shot# -3: ray code 2.2: 34 rays traced
shot# -3: ray code 3.2: 26 rays traced
shot# 3: ray code 2.2: 65 rays traced
shot# 3: ray code 3.2: 73 rays traced
|----------------------------------------------------------------|
| |
| total of 2089 rays consisting of 21239 points were traced |
| |
| model consists of 4 layers and 40 blocks |
| |
|----------------------------------------------------------------|
Number of data points used: 477
RMS traveltime residual: 0.068
Normalized chi-squared: 46.331
Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG IEEE_DIVIDE_BY_ZERO IEEE_OVERFLOW_FLAG IEEE_DENORMAL
Now, start your work with rayinvr!
This section lists what errors the original rayinvr throws and how I fix them.
Just abandon unilink
command and use $(FC)
instead. Open the Makefile
that throws this error, and change the line:
unilink ${TRAMP_OBJS}
to
$(FC) -o main ${TRAMP_OBJS}
PS: $(FC)
will be replaced with your Fortran Compiler, for example gfortran
.
Both f77
and gfortran
do not support "Variable FORMAT expression", which is used in several rayinvr programs. For example, pltlib.f:198
reads:
5 format(i2/i10/4e15.5,<nchar>a1)
This line includes a "Variable FORMAT expression", in which nchar
is an integer variable. The error throwed out is like the following:
gfortran Error: Unexpected element ‘<’ in format string at (1)
To fix this issue, there are 2 common ways:
-
As GUN Fortran recommended, we can construct a format string dynamicly. See here
-
Simply replace
<nchar>
with a number which is large enough, say10000
. Now, theformat
line will looks like this:5 format(i2/i10/4e15.5,10000a1)
gfortran
does not allow using $
in variable name by default. Or it will throw the following error:
# when building xrayinvr
# in rayinvr/trc.f:498:17:
Fatal Error: Invalid character ‘$’ at (1). Use ‘-fdollar-ok’ to allow it as an extension compilation terminated
To fix this error, you should add option -fdollar-ok
to gfortran
. To be more detail, add this option to FFLAGS
at the beginning of each Makefile
file:
FFLAGS = -O -fdollar-ok
pltlib/xbuplot.c
uses Xlib
to plot graphics. Foreground and background settings locates at line 99 and 100:
/* create opaque window */
win = XCreateSimpleWindow (display, RootWindow (display, screen_num),
x, y, win_width, win_height, border_width,
WhitePixel (display, screen_num), // foreground
BlackPixel (display, screen_num)); // background
The default precision of v.in
is f7.2
. If you want to read a higher precision version of v.in
(say, f8.3
), just open the main.f
that reads the v.in
, change the lines:
15 format(i2,1x,10f7.2)
25 format(3x,10i7)
25 format(3x,10(5x,i2))
to:
15 format(i2,1x,10f8.3)
25 format(3x,10i8)
25 format(3x,10(6x,i2))
Changed rayinvr/main.f:890
(and many others):
if(abs(xshotr-xshotf).lt..001.and.idr(is).eq.idf) then
to:
if(abs(xshotr-xshotf).lt..0001.and.idr(is).eq.idf) then
Changed pltsyn/pltsec.f:253
:
108 if(namp.eq.0) write(*,*, fmt="(/
to:
108 if(namp.eq.0) write(*, fmt="(/
Enlarged some parameters in rayinvr/rayinvr.par
and tramp/tramp.par
for processing larger models.
Promoted prayi
to 100000
to enable huge tx.in
files (>100000 lines).
Add -fdefault-real-8 -fdefault-double-8 -fdefault-integer-8
options to FFLAGS
in Makefile
, and replace fixed declaritions (real*4
) in the code with flexible ones (real
).