UCVM Model Integration Guide

From SCECpedia
Revision as of 22:24, 2 July 2014 by Davidgil (talk | contribs)
Jump to navigationJump to search

Introduction

UCVM 14.7.0 introduced a new interface designed to make installing and adding new models easier. Unlike previous versions of UCVM, starting with UCVM 14.7.0, UCVM will not need to know about the model at compile-time in order to make use of it. This means that model developers can more readily use UCVM's plotting utilities, meshing utilities, and other capabilities with their models.

Please note that this guide is only for systems that support dynamic linking. If you are on a system that only supports static linking, you will need to follow the steps at the end of the guide to make the model work with UCVM.

Interface Description

Directory Structure

UCVM searches and reads models that are installed in a standardized format. Suppose that you have UCVM installed in /home/user/ucvm-14.6.0. All models are installed in the "model" directory and must follow this format to be included:

/home/user/ucvm-14.7.0/model/[name]/lib/lib[name].so

So, if we are trying to install a model named "acme", we would need our shared object library to be at:

/home/user/ucvm-14.7.0/model/acme/lib/libacme.so

Basic Structures

All UCVM models work in the following basic manner:

  1. Take as input latitude, longitude, and depth, with spherical earth co-ordinates using the WGS84 ellipsoid.
  2. Return material properties for that point. The material properties consist of one or more of Vp (m/s), Vs (m/s), Density (g/cm^3), Qp, and/or Qs.

UCVM passes the input latitude, longitude, and depth through a structure which is defined as follows:

typedef struct basic_point_t {
    double longitude;    // Longitude in degrees
    double latitude;    // Latitude in degrees
    double depth;    // Depth in meters
} basic_point_t;

All models need to then read in points in the above format and return material properties in the following format:

typedef struct basic_properties_t {
    double vp;    // Vp in meters per second
    double vs;    // Vs in meters per second
    double rho;    // Density in grams per cubic centimeter
    double qp;    // Qp
    double qs;    // Qs
} basic_properties_t;

Model Operation

Models called from UCVM undergo the following lifecycle:

  1. Initialization - during this period, the model is initialized and should load any necessary data to memory as disk can be relatively slow. It's also recommended that the model pre-compute as much as possible with regards to projections, coefficients, and so on.
  2. Query - after models are initialized they must be ready to accept queries. Queries are arrays of the basic_point_t structure, as described in the structures section, and a pre-malloced pointer to an array of basic_properties_t, which will contain the material properties. If no properties are available, models are advised to return -1 for each of the entries in the basic_properties_t structure.
  3. Finalize - models who are called to finalize must free up their resources.

Function Definitions

There are four functions that must be implemented:

int model_init(const char *dir, const char *label)
Description: Called to initialize the model and load whatever contents are necessary into memory.
Parameters:

  • dir - The directory in which UCVM is located (e.g. /home/user/ucvm-14.7.0).
  • label - The model name (e.g. acme). So the model's full directory is always [dir]/model/[label].

Returns: 0 if the model initialization worked, 1 if it didn't.

int model_query(basic_point_t *points, basic_properties_t *data, int numpts)
Description: Gives an array of numpts points and writes material properties to an equal number of basic_properties_t structures in data.
Parameters:

  • points - The array of points, in WGS84 ellipsoid, latitude, longitude format for which the model should retrieve material properties.
  • data - The array of material properties that are returned.
  • numpts - The number of points, and material properties, to use.

Returns: 0 if query was successful, 1 if there was an error encountered (note an error in this case does not mean outside of the model region, rather it means an unrecoverable issue such as a bad projection, or something like that).

int model_finalize()
Description: Frees up all used memory and shuts the model down.
Returns: 0 if the free was successful, 1 if not.

int model_version(char *ver, int len)
Description: Returns a unique version identifier for your model (e.g. "Acme 1.0").
Parameters:

  • ver - The version string buffer to which the version identifier should be written.
  • len - The maximum number of characters to return.

Returns: 0 if the version was written successfully, 1 if not.

Basic Tutorial Model

Code Description

This tutorial will show how to integrate a simple, fictitious model into UCVM. Let's suppose that we have a very simple model which simply returns Vp = (2000 + latitude)m/s, Vs = (1000 + longitude)m/s, and density = (2000 + depth)g/cm^3, for every point within the model boundaries. Of course, this is a completely fake model, but it will suffice to show the general idea of implementation within UCVM.

We would require no initialization for this model, so our model_init would be something like:

int model_init(const char *dir, const char *label) {
    return 0;
}

For our query function, we would need to loop through each point and return back our fake material properties:

int model_query(basic_point_t *points, basic_properties_t *data, int numpts) {
    int i = 0;
    for (i = 0; i < numpts; i++) {
        data[i].vp = 2000 + points[i].latitude;    // Set Vp for this point.
        data[i].vs = 1000 + points[i].longitude    // Set Vs for this point.
        data[i].rho = 2000 + points[i].depth    // Set density for this point.
        data[i].qp = -1;    // Model does not have Qp.
        data[i].qs = -1;    // Model does not have Qs.
    }
    return 0;
}

We also require no memory clean-up, so our finalize function is very simple:

int model_finalize() {
    return 0;
}

Finally, let's call our model "Acme":

int model_ver(char *ver, int len) {
    int verlen;
    verlen = strlen("Acme");
    if (verlen > len - 1) {
        verlen = len - 1;
    }
    memset(ver, 0, len);
    strncpy(ver, "Acme", verlen);
    return 0;
}

Compiling and Installing

The entire code is as follows:

acme.c
typedef struct basic_point_t {
    double longitude;    // Longitude in degrees
    double latitude;    // Latitude in degrees
    double depth;    // Depth in meters
} basic_point_t;

typedef struct basic_properties_t {
    double vp;    // Vp in meters per second
    double vs;    // Vs in meters per second
    double rho;    // Density in grams per cubic centimeter
    double qp;    // Qp
    double qs;    // Qs
} basic_properties_t;