Skip to content

FORTRAN API

Philip Maechling edited this page Sep 1, 2022 · 1 revision

Calling UCVM using Fortran can be done after you have installed UCVM from source code. You must include the UCVM library, the Proj.4 library, the e-tree library, as well as any velocity model libraries that you have compiled into UCVM. For CVM-H, please note that there are actually two libraries required: lvxapi and lgeo. Because the default convention for calling C programs from Fortran automatically appends an underscore to the end of the function name, you must turn that off via a flag called "fno-underscoring". This will make the Fortran compiler try and find foo() instead of foo_().
As an example, suppose we have a Fortran file, example.f, that calls UCVM. We have compiled UCVM with CVM-S and CVM-H. The code to compile example.f would be as follows:

gfortran example.f -o ./example -L/path/to/ucvm-14.3.0/lib -L./path/to/ucvm-14.3.0/model/cvms4/lib -L/path/to/ucvm-14.3.0/model/cvmh1191/lib -L/path/to/ucvm-14.3.0/lib/proj-4/lib -L/path/to/ucvm-14.3.0/lib/euclid3/libsrc -lucvm -lcvms -lvxapi -lgeo -lproj -letree -fno-underscoring
The basic structure of how to call UCVM within Fortran is outlined in the example below.

Example.f

                program example
         
        c       UCVM Configuration Location
                CHARACTER(LEN=80) ucvmconf
        c       Model Name
                CHARACTER(LEN=4) model 
        c       Number of points we're passing to ucvm_query
                INTEGER pts      
         
        c       The UCVM point data structure. 
        c       coord(1) is longitude
        c       coord(2) is latitutde
        c       coord(3) is depth
                TYPE :: ucvm_point_t
                       REAL*8 coord(3)
                END TYPE ucvm_point_t
         
        c       Generic property structure
        c       Source is where it comes from
        c       vp is P-wave velocity in m/s
        c       vs is S-wave velocity in m/s
        c       rho is density in kg/m^3
                TYPE :: ucvm_prop_t
                        INTEGER source
                        REAL*8 vp
                        REAL*8 vs
                        REAL*8 rho
                END TYPE ucvm_prop_t
         
        c       Returned data structure
                TYPE :: ucvm_data_t
                        REAL*8 surf
                        REAL*8 vs30
                        REAL*8 depth
                        INTEGER domain
                        REAL*8 shift_cr
                        REAL*8 shift_gtl
                        type(ucvm_prop_t) crust
                        type(ucvm_prop_t) gtl
                        type(ucvm_prop_t) cmb
                END TYPE ucvm_data_t
         
        c       For our example we'll query five points
                type(ucvm_point_t) point(5)
        c       And we'll get back five sets of material properties
                type(ucvm_data_t) returnData(5)
         
        c       Number of points is 5.
                pts = 5
         
        c       We'll start at -118, 34 at 0 depth and go down by 1000m
        c       each step
                do 10 i = 1, 5
                        point(i)%coord(1) = -118
                        point(i)%coord(2) = 34
                        point(i)%coord(3) = (i - 1) * 1000
        10      continue
         
        c       Where is our configuration file?
                ucvmconf = "/home/scec-01/davidgil/ucvm.conf" // CHAR(0)
         
        c       What model are we querying?
                model = "cvms"
         
        c       Initialize UCVM
                call ucvm_init(ucvmconf)
         
        c       Add the model to UCVM
                call ucvm_add_model(model)
         
        c       Query the model. Note that the number of points is passed
        c       by value, not reference.
                call ucvm_query(%VAL(pts), point, returnData)
         
                print *, model, " results for lon -118, lat 34"
         
        c       Print out the results.
                do 20 i = 1, 5
                        print *, "Depth ", (i - 1) * 1000
                        print *, "Vs ", returnData(i)%crust%vs 
                        print *, "Vp ", returnData(i)%crust%vp 
                        print *, "Rho ", returnData(i)%crust%rho
        20      continue
         
        c       Close UCVM now that we've queried the points 
                call ucvm_finalize()
         
                end

GCC Fortran 4.3+ is required for this example to work.