Using Libsim from Python

Libsim lets VisIt connect to a simulation and access data that the simulation wants to expose to VisIt for plotting and analysis. Libsim lets VisIt connect C, C++, and Fortran simulations. VisIt 2.3.0 provides Python bindings for libsim, enabling VisIt to connect to simulations written in Python. The bindings are built using SWIG.

Example simulations

Here are links to some example simulations:

Differences

For the most part, the using libsim from Python looks like it does in C but there are some differences that you should know about.

Including files

#include <VisItControlInterface_V2.h>
#include <VisitDataInterface_V2.h>

becomes

# Add VisIt's lib directory to the Python module path. Use the right path and platform.
import sys
sys.path.append("/path/to/visit/2.3.0/linux-x86_64/lib")

from simV2 import *

Alloc functions

All of the data object _alloc() functions that allocate objects return a visit_handle since they are not allowed to modify a visit_handle that was passed by reference.

visit_handle h = VISIT_INVALID_HANDLE;
if(VisIt_VariableData_alloc(&h) == VISIT_OKAY)
{
    // do something with h
}

becomes

h = VisIt_VariableData_alloc()
if h != VISIT_INVALID_HANDLE:
    # do something with h

Parallel broadcast callbacks

The callbacks that are used to broadcast int and string for parallel communications must return the broadcasted value in the Python callbacks since the input arguments cannot be modified. These examples use VisIt's mpicom wrapper for MPI. Also, note that the Python examples have a self parameter because they are method arguments of a Simulation class. That's just how the example was written.

static int visit_broadcast_int_callback(int *value, int sender)
{
    return MPI_Bcast(value, 1, MPI_INT, sender, MPI_COMM_WORLD);
}

static int visit_broadcast_string_callback(char *str, int len, int sender)
{
    return MPI_Bcast(str, len, MPI_CHAR, sender, MPI_COMM_WORLD);
}

becomes

class Simulation:

    # A lot of stuff has been omitted

    def broadcast_int(self, ival, sender):
        if self.par_rank == 0:
            ret = mpicom.broadcast(ival)
        else:
            ret = mpicom.broadcast()
        return ret

    def broadcast_string(self, sval, slen, sender):
        if self.par_rank == 0:
            ret = mpicom.broadcast(sval)
        else:
            ret = mpicom.broadcast()
        return ret