Python APIΒΆ

Most of the previous sections about the user interface routines applies to the Python binding. Naturally, some specifics concerning Python come into play.

The module asynch_interface for Python can be found in the directory asynch_py in the ASYNCH root directory. The module can be loaded a in Python script with a command such as:

from asynch_py.asynch_interface import asynchsolver

The routines in the Python interface can be found in Section [sec: user interface routines]. These routines are predominantly the same as those from the C interface, with the exception of the initialization and finalization routines (Sections [sec: solver initialization] and [sec: asynchfree], respectively).

To demonstrate the usage of these routines in Python, consider the following code, which is analogous to the program given in Section [sec: interface usage]:

#Include the ASYNCH Python interface
from asynch_py.asynch_interface import asynchsolver
import sys

#Prepare system
asynch = asynchsolver()
asynch.Parse_GBL(sys.argv[1])
asynch.Load_System()

#Prepare outputs
asynch.Prepare_Temp_Files()
asynch.Write_Current_Step()
asynch.Prepare_Peakflow_Output()
asynch.Prepare_Output()

#Advance solver
asynch.Advance(1)

#Take a snapshot
asynch.Take_System_Snapshot(None)

#Create output files
asynch.Create_Output(None)
asynch.Create_Peakflows_Output()

#Cleanup
asynch.Delete_Temporary_Files()

The contents of the source code asynchdist.py is essentially the program above. The module sys is loaded to read the filename of the global file from the command line. An instance of the asynchsolver class is created and stored as asynch. From this object, all the routines from the interface are called. As is traditional in Python, clean up of the asynchsolver instance is performed automatically.

Creating custom models and outputs with the Python interface is similar to that of the C interface. See Sections [sec: custom outputs] and [sec: custom models]. Any routines passed into the Python interface written in Python must be decorated as an appropriate function type. The available data types are

Type Description
ASYNCH_F_DATATYPE ODE
ASYNCH_RKSOLVER_DATATYPE Runge-Kutta Solver
ASYNCH_CONSISTENCY_DATATYPE System Consistency
ASYNCH_ALG_DATATYPE Algebraic Equations
ASYNCH_STATECHECK_DATATYPE State Check
ASYNCH_OUTPUT_INT_DATATYPE Output Time Series with Integer Values
ASYNCH_OUTPUT_DOUBLE_DATATYPE Output Time Series with Double Precision Values
ASYNCH_PEAKOUTPUT_DATATYPE Output Peakflow Routine
ASYNCH_SETPARAMSIZES_DATATYPE SetParmSizes Routine for Custom Models
ASYNCH_CONVERT_DATATYPE ConvertParams Routine for Custom Models
ASYNCH_ROUTINES_DATATYPE InitRoutines Routine for Custom Models
ASYNCH_PRECALCULATIONS_DATATYPE Precalculations Routine for Custom Models
ASYNCH_INITIALIZEEQS_DATATYPE ReadInitData Routine for Custom Models

Decorating a routine in Python can be done with the @ symbol. For instance, the following is the definition of a function for converting units of state parameters:

@ASYNCH_CONVERT_DATATYPE
def ConvertParams_MyModel(params,model_type,lib_ptr):
  params.contents.ve[1] *= 1000
  params.contents.ve[2] *= 1e6

A function decorated with an ASYNCH function type cannot be called as a regular Python function. It should only be called from a routine written in C.

The routines for creating a custom model have one additional argument available. This is a library object to the ASYNCH C routines. Such routines may be used by and given to Python interface functions. For instance, consider this example routine used for the ReadInitData routine:

@ASYNCH_ROUTINES_DATATYPE
def InitRoutines_MyModel(link_p, model_type, exp_imp,dam,lib_p):
  lib = cast(lib_p,py_object).value
  link = link_p.contents

  if link.res:
    link.f = LinearHillslope_Reservoirs_MyModel
    link.RKSolver = cast(lib.ForcedSolutionSolver, ASYNCH_RKSOLVER_DATATYPE)
  else:
    link.f = LinearHillslope_MyModel
    link.RKSolver = cast(lib.ExplicitRKSolver, ASYNCH_RKSOLVER_DATATYPE)
    link.alg = cast(None,ASYNCH_ALG_DATATYPE)
    link.state_check = cast(None, ASYNCH_STATECHECK_DATATYPE)
    link.CheckConsistency = cast(lib.CheckConsistency_Nonzero_AllStates_q, ASYNCH_CONSISTENCY_DATATYPE)

In this sample, the Runge-Kutta methods are set to functions defined in the ASYNCH library. Also note that if a routine does not need to be set (here, the algebraic and state check routines), then the routine is set to None casted as the appropriate function data type. The SetParamSizes routine for creating custom models requires creating an array. This can be done with a call to the function Allocate_CUINT_Array from the ASYNCH library. It requires only one argument, the size of the array, and its return value can be directly set to the member dense_indices.