C API

ASYNCH comes with a collection of routines to access specific details of the underlying solver structure. This allows a user to construct his or her own programs, while making calls to the solver in particular ways. This is useful for modifying how the solvers behave, and for producing more specialized outputs. A user can also specify his or her own models in a separate module. Currently, interface routines exist for the C/C++ and Python programming languages.

Typical Interface Usage

In this section, we provide an overview of how to use the API routines for running simulations. Regardless of the language, the general order of calling API routines is the same. Further routines may be added to increase flexibility.

A basic program that uses the ASYNCH solvers to perform calculations and takes advantage of all the features of a global file is the following (written in C):

//Make sure we finalize MPI
void asynch_onexit(void)
{
    int flag;
    MPI_Finalized(&flag);
    if (!flag)
        MPI_Finalize();
}

int main(int argc,char* argv[])
{
  int res;
  char *global_filename = argv[1];

  //Initialize MPI stuff
  res = MPI_Init(&argc, &argv);
  if (res == MPI_SUCCESS)
      atexit(asynch_onexit);
  else
  {
      print_err("Failed to initialize MPI");
      exit(EXIT_FAILURE);
  }

  //Init asynch object and the river network
  AsynchSolver asynch;
  Asynch_Init(&asynch, MPI_COMM_WORLD);
  Asynch_Parse_GBL(&asynch, global_filename);
  Asynch_Load_Network(&asynch);
  Asynch_Partition_Network(&asynch);
  Asynch_Load_Network_Parameters(&asynch, 0);
  Asynch_Load_Dams(&asynch);
  Asynch_Load_Numerical_Error_Data(&asynch);
  Asynch_Initialize_Model(&asynch);
  Asynch_Load_Initial_Conditions(&asynch);
  Asynch_Load_Forcings(&asynch);
  Asynch_Load_Save_Lists(&asynch);
  Asynch_Finalize_Network(&asynch);
  Asynch_Calculate_Step_Sizes(&asynch);

  //Prepare output files
  Asynch_Prepare_Temp_Files(&asynch);
  Asynch_Write_Current_Step(&asynch);
  Asynch_Prepare_Peakflow_Output(&asynch);
  Asynch_Prepare_Output(&asynch);

  //Perform the calculations
  Asynch_Advance(&asynch, 1);

  //Create output files
  Asynch_Take_System_Snapshot(&asynch, NULL);
  Asynch_Create_Output(&asynch, NULL);
  Asynch_Create_Peakflows_Output(&asynch);

  //Clean up
  Asynch_Delete_Temporary_Files(&asynch);
  Asynch_Free(&asynch);

  return EXIT_SUCCESS;
}

Details of each function call can be found in User Interface Routines.

The program begins by initializing the asynchsolver object. The MPI communicator consisting of all processes (MPI_COMM_WORLD) is used for the calculations. Next, the global file specified as a command line argument to the program is parsed. Based upon the information specified by the global file, the different components of the network are constructed.

Next, the outputs for the program are initialized. The files for holding calculation results while the program runs is initialized (i.e. the temporary files). The initial values of the states are written to disk. Any initializations needed for the output peakflow and output time series sources are done.

With a call to Asynch_Advance, the calculations are performed. Any time series results are temporarily stored in the temporary files.

Once the calculations are complete, any necessary outputs are created (snapshot, output time series, output peakflow data). This could include writing to files or database tables, depending upon the options selected in the global file.

Lastly, clean up routines are called. The temporary files are deleted. The asynchsolver object is also deleted from memory with a call to . Note that this routine does not need to be called if using the interface functions from a language that supports automatic garbage collection.

Of course, outputting more information might be useful (timing results, command line parameter checking, results printed to screen, etc), and additional features may be needed (outputting data to multiple sources, creating peakflow data over intervals of time, etc). However, this is the basic structure needed to perform simulations. The program src/asynch_cli.c (the asynch command) is essentially the above program, with command-line options and information printed to screen; Simulation.run of the Python package does the same calls.

User Interface Routines

In this section, routines for operating the solver are described. These routines can be used to create an instance of an ASYNCH solver, and manipulate properties such as total simulation time, when data output occurs, etc… Creation of custom outputs is discussed in Custom Outputs and creation of custom models is discussed in Custom Models.

Solver Constructor / Destructor

AsynchSolver *Asynch_Init(MPI_Comm comm, bool verbose)

This routine initializes an instance of an AsynchSolver.

Multiple solvers could be created if multiple problems are to be solved. An instance of an AsynchSolver contains all the relevant data structures and information to solve the equations for an underlying model. An AsynchSolver object should be destroyed with a call to Asynch_Free.

See also

Asynch_Free

Parameters:
  • comm – The MPI communicator to use with this solver object.

Pre:

MPI should be properly initialized with MPI_Init before calling Asynch_Init.

Returns:

A pointer to an AsynchSolver object.

void Asynch_Free(AsynchSolver *asynch)

This routine deallocates the memory occupied by an AsynchSolver object created with a call to Asynch_Init.

See also

Asynch_Init

Parameters:
  • asynch – A pointer to a AsynchSolver object to free.

Solver Initialization

void Asynch_Parse_GBL(AsynchSolver *asynch, char *filename)

This routine opens and processes a global file.

It reads all specified database connection files, but does not process any other input file. An error in this routine is considered fatal, and results in a call to the routine MPI_Abort on the communicator used to create asynch.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • filename – Path of a global file.

Pre:

asynch should be initialized with Asynch_Init before calling Asynch_Parse_GBL.

void Asynch_Load_Network(AsynchSolver *asynch)

This routine processes topology inputs for the AsynchSolver object as set in the global file read by Asynch_Parse_GBL.

This initializes each Link object and sets their parent and child information. Generally, this is the first initialization routine to call after parsing a global.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

Asynch_Parse_GBL should be called before Asynch_Load_Network.

void Asynch_Partition_Network(AsynchSolver *asynch)

This routine assigns the Links of the asynchsolver object to the MPI processes.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine must be called after Asynch_Load_Network.

void Asynch_Load_Network_Parameters(AsynchSolver *asynch)

This routine processes parameter inputs for the AsynchSolver object as set in the global file read by Asynch_Parse_GBL.

Setting load_all to true causes every MPI process to store the parameters at every Link.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine can be called before Asynch_Partition_Network only if load_all is set to true.

void Asynch_Load_Dams(AsynchSolver *asynch)

This routine processes the is_dam inputs for the AsynchSolver object as set in the global file read by.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine should be called after Asynch_Partition_Network and Asynch_Load_Network_Parameters have been called.

void Asynch_Load_Numerical_Error_Data(AsynchSolver *asynch)

This routine processes numerical solver inputs for the AsynchSolver object as set in the global file read by Asynch_Parse_GBL.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine should be called after Asynch_Partition_Network has been called.

void Asynch_Initialize_Model(AsynchSolver *asynch)

This routine sets the model specific routines for each link for the AsynchSolver object as set in the global file read by Asynch_Parse_GBL.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine should be called after Asynch_Partition_Network and Asynch_Load_Network_Parameters have been called.

void Asynch_Load_Initial_Conditions(AsynchSolver *asynch)

This routine processes the initial condition inputs for the AsynchSolver object as set in the global file read by Asynch_Parse_GBL.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine should be called after Asynch_Partition_Network and Asynch_Initialize_Model have been called.

void Asynch_Load_Forcings(AsynchSolver *asynch)

This routine processes the forcing inputs for the AsynchSolver object as set in the global file read by Asynch_Parse_GBL.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine should be called after Asynch_Partition_Parameters has been called.

void Asynch_Load_Save_Lists(AsynchSolver *asynch)

This routine processes save list inputs for the AsynchSolver object as set in the global file read by Asynch_Parse_GBL.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine should be called after Asynch_Partition_Network has been called.

void Asynch_Finalize_Network(AsynchSolver *asynch)

This routine checks that all inputs are loaded for the AsynchSolver object.

Some small final initializations are also performed.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine should be called as the last initialization routine.

Integration

void Asynch_Calculate_Step_Sizes(AsynchSolver *asynch)

This routine processes calculates appropriate step sizes for the integrators at each link in the AsynchSolver object.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine must be called before a call to Asynch_Advance, and after all initializations are performed.

void Asynch_Advance(AsynchSolver *asynch, int print_level)

This routine advances the numerical solver up to the time set in maxtime.

See Section [sec: model type and maxtime]. Calculations to solve the model differential and algebraic equations are performed, using forcing data as needed.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • print_level – If 0, no time series information is produced. Otherwise, time series information is produced.

Pre:

This routine should be called after Asynch_Partition_Network has been called.

Timeseries Output

void Asynch_Prepare_Output(AsynchSolver *asynch)

This routine prepares the output sources for time series data.

Preparation includes creating files or database tables.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine must be called before any time series data can be produced.

int Asynch_Create_Output(AsynchSolver *asynch, char *file_suffix)

This routine takes all data written to temporary files and moves them to a final output destination for time series data.

If the output format is data file or CSV file, then the string additional_out is appended to the filename. If additional_out is NULL, then no appending to the filename occurs.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • file_suffix – String appended to the end of any output filename. \ return Returns 0 if output is written, -1 means there is no data to output.

void Asynch_Prepare_Peakflow_Output(AsynchSolver *asynch)

This routine prepares the output sources for the peakflow data.

Preparation includes creating files or database tables.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine must be called before any peakflow data can be produced.

int Asynch_Create_Peakflows_Output(AsynchSolver *asynch)

This routine takes all calculated peakflow data and writes them to a final output destination.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use. \ return Returns 0 if output is written, -1 means there is no data to output.

int Asynch_Write_Current_Step(AsynchSolver *asynch)

This routine writes the current state of each link to temporary files for every link where a time series output has been specified.

Normally, calling Asynch_Advance with the print_flag set is enough to write output time series. However, advancing an AsynchSolver object without the print_flag set or calls that modify how data is outputted to the temporary files will cause data to not be written for some times. This routine can be called to commit missing data.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Returns:

Returns 0 if the step is written, 1 if no temporary file is available.

Temporary files

void Asynch_Prepare_Temp_Files(AsynchSolver *asynch)

This routine prepares the temporary files for time series data.

Preparation includes creating files or database tables.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Pre:

This routine must be called before any time series data can be calculated. A call to Asynch_Advance with the print_flag set before preparing temporary files will create an error.

int Asynch_Delete_Temporary_Files(AsynchSolver *asynch)

This routine deletes the tempfiles for asynch.

This is useful for cleaning up temporary files at the end of a simulation, or for deleting the files if they must be reconstructed.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Returns:

Returns 0 if the tempfiles were deleted, 1 if no tempfiles exist, and 2 if an error occurred.

int Asynch_Set_Temp_Files(AsynchSolver *asynch, double set_time, void *set_value, unsigned int output_idx)

This routine moves the temporary file pointer to a previous value.

All future values are deleted. The point where the pointer is moved is determined by set_value, which is in the output series determined by output_idx. The local time where the next data will be written for each link is set_time.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • set_time – The local time corresponding the step where the temp files will be set.

  • set_value – The value to which the tempfiles will be set.

  • output_idx – The index of the series output of which set_value corresponds.

Pre:

A warning occurs if set_value is not found for a link, and that link’s tempfile pointer is not changed.

Returns:

Returns 0 if the temporary files are set, 1 if a warning occurred, 2 if there was an error setting the files.

Snapshots

int Asynch_Take_System_Snapshot(AsynchSolver *asynch, char *prefix)

This routine processes calculates appropriate step sizes for the integrators at each link in the AsynchSolver object.

This routine creates snapshot output data to either a recovery file or a database table.

The current value of every state at every link is outputted. If a recovery file was the format specified in the global file, then the string name is appended to the end of the recovery filename. This appending does not occur if name is NULL or if a database table is the selected format.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • prefix – String to prepend to the snapshot output filename.

  • asynch – A pointer to a AsynchSolver object to use.

  • prefix – String to prepend to the snapshot output filename.

Pre:

This routine must be called before a call to Asynch_Advance, and after all initializations are performed.

Returns:

An error code. Returns 0 if a snapshot was made, 1 if an error was encountered, -1 if no snapshot is made.

Returns:

Returns 0 if a snapshot was made, 1 if an error was encountered, -1 if no snapshot is made.

int Asynch_Get_Snapshot_Output_Name(AsynchSolver *asynch, char *filename)

This routine gets the filename of the output snapshot file.

If a database connection is used, then the contents of snapshotname is not modified. The Python interface routine returns the string with the filename instead of taking it as an argument.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • filename – Name of the snapshot output filename returned.

Returns:

0 if the filename was set successfully. 1 otherwise.

int Asynch_Set_Snapshot_Output_Name(AsynchSolver *asynch, char *filename)

This routine sets the filename of the output snapshot file.

If a database connection is used, then no changes are made.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • filename – Name to set the snapshot output filename.

Returns:

0 if the filename was set successfully. 1 otherwise.

Getters and Setters

unsigned short Asynch_Get_Model_Type(AsynchSolver *asynch)

This routine sets the model type.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Returns:

The model type

void Asynch_Set_Model_Type(AsynchSolver *asynch, unsigned short type)

This routine returns the model type.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • type – The model type.

double Asynch_Get_Total_Simulation_Duration(AsynchSolver *asynch)

This routine returns the value of duration, as defined in Section[sec:simulation period].

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Returns:

The current duration of the simulation time of the AsynchSolver object (unit is model dependant, but usually minutes is used).

void Asynch_Set_Total_Simulation_Duration(AsynchSolver *asynch, double duration)

This routine returns the value of duration, as defined in Section[sec:model type and duration].

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • duration – The value to set the maximum simulation time.

This routine returns the total number of links in the network of asynch.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Returns:

Number of links in the network

This routine returns the total number of links assigned to the current MPI process in the network of asynch.

This number represents the total number of links whose differential and algebraic equations are solved by the current process.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

Returns:

Number of links assigned to the current MPI process

Database

void Asynch_Set_Database_Connection(AsynchSolver *asynch, const char *conn_string, unsigned int conn_idx)

This routine sets a new database for an input or output.

If information for a database has already been set, it is released, and the new connection information is set. Database information includes hostname, username, password, etc. This is the same information that is available in the header of database connection files (see Section [sec: database connection files]). Several database connections exist for every AsynchSolver object. conn_idx can take the values:

  • ASYNCH_DB_LOC_TOPO

  • ASYNCH_DB_LOC_PARAMS

  • ASYNCH_DB_LOC_INIT

  • ASYNCH_DB_LOC_RSV

  • ASYNCH_DB_LOC_HYDROSAVE

  • ASYNCH_DB_LOC_PEAKSAVE

  • ASYNCH_DB_LOC_HYDRO_OUTPUT

  • ASYNCH_DB_LOC_PEAK_OUTPUT

  • ASYNCH_DB_LOC_SNAPSHOT_OUTPUT

  • ASYNCH_DB_LOC_FORCING_START

The last value for conn_idx is the database connection for the first forcing specified in the global file. Database connections for other forcings can be access sequentially. For example, to access the forcing with index 2 (the third forcing in a global file), set conn_idx as ASYNCH_DB_LOC_FORCING_START + 2

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • conn_string – A connection string

  • conn_idx – Connection index

Forcing

int Asynch_Activate_Forcing(AsynchSolver *asynch, unsigned int idx)

This routine activates a forcing for use.This means when a call to the routine Asynch_Advance is made, the forcing with index idx will be applied for calculations.By default, all forcings set in a global file are initially active.This routine has the opposite effect of Asynch_Deactivate_Forcing.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • idx – The index of the forcing to activate.

Returns:

Returns 0 if the forcing was activated, 1 if an error occurred

int Asynch_Deactivate_Forcing(AsynchSolver *asynch, unsigned int idx)

This routine deactivates a forcing for use.

This means when a call to the routine Asynch_Advance is made, all values for the forcing with index idx will be taken as 0. By default, all forcings set in a global file are initially active. This routine has the opposite effect of Asynch_Activate_Forcing.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • idx – The index of the forcing to activate.

Returns:

Returns 0 if the forcing was activated, 1 if an error occurred

unsigned int Asynch_Get_First_Forcing_Timestamp(AsynchSolver *asynch, unsigned int forcing_idx)

This routine returns the first timestamp for a forcing.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • forcing_idx – An index of a forcing.

Pre:

This can only be used if the forcing with index forcing_idx is using a format of binary files, gz binary files, or database table. See Section [sec: forcing inputs] for adescription of these formats.

Returns:

The timestamp of the last timestamp for the forcing with index forcing_idx.

void Asynch_Set_First_Forcing_Timestamp(AsynchSolver *asynch, unsigned int unix_time, unsigned int forcing_idx)

This routine sets the first timestamp for a forcing.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • unix_time – The value to set the first forcing timestamp.

  • forcing_idx – An index of a forcing.

Pre:

This can only be used if the forcing with index forcing_idx is using a format of binary files, gz binary files, or database table. See Section [sec: forcing inputs] for adescription of these formats.

Returns:

The timestamp of the last timestamp for the forcing with index forcing_idx.

unsigned int Asynch_Get_Last_Forcing_Timestamp(AsynchSolver *asynch, unsigned int forcing_idx)

This routine returns the last timestamp for a forcing.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • forcing_idx – An index of a forcing.

Pre:

This can only be used if the forcing with index forcing_idx is using a format of binary files, gz binary files, or database table. See Section [sec: forcing inputs] for adescription of these formats.

Returns:

The timestamp of the last timestamp for the forcing with index forcing_idx.

void Asynch_Set_Last_Forcing_Timestamp(AsynchSolver *asynch, unsigned int unix_time, unsigned int forcing_idx)

This routine sets the last timestamp for a forcing.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • unix_time – The value to set the last forcing timestamp.

  • forcing_idx – An index of a forcing.

Pre:

This can only be used if the forcing with index forcing_idx is using a format of binary files, gz binary files, or database table. See Section [sec: forcing inputs] for adescription of these formats.

Returns:

The timestamp of the last timestamp for the forcing with index forcing_idx.

void Asynch_Set_Forcing_DB_Starttime(AsynchSolver *asynch, unsigned int unix_time, unsigned int forcing_idx)

This routine sets the start time used for a forcing.

This value is used for converting between timestamps in a database table and the local time of the solvers. This can only be used if the forcing with index forcing_idx is using a format of database table. See Section [sec: forcing inputs] for a description of this format.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • unix_time – The value to set the start timestamp.

  • forcing_idx – An index of a forcing.

State Variables Getters and Setters

void Asynch_Set_Init_File(AsynchSolver *asynch, char *filename)

This routine sets a file for reading initial value data.

The init_flag is set based upon the extension of filename. The initial data is NOT read while executing this routine. A call to Asynch_Load_System is needed to set the filename. This routine cannot be used to set the format to a database connection.

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • filename – Filename to use for initial value data.

void Asynch_Set_System_State(AsynchSolver *asynch, double unix_time, double *states)

This routine sets the current time of each link to t_0 and the current state to the vector in the array values.

The vectors are assumed to be in the same order as the links provided by the topology source specified in the global file (see Section [sec: topology]).

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • unix_time – The timestamp to set at each link.

  • states – The vector of the current state of each link.

State Variables Getters and Setters

Custom Outputs

Time series outputs can be customized so as to produce results specific to a particular model. For instance, fluxes that are used internally to the model, or values that are not needed at all for computing state solutions, may be outputted.

To create a custom output, specify the name of your new output in the global file (see Time Series Output). Next, in your program after reading the global file but before performing simulations, call the routine Asynch_Set_Output to set your output. Then perform any calculations or further modifications as usual.

A custom routine must be provided by the user for determining how the output is calculated. The specifications for this function are provided below.

Similarly, custom peakflow outputs can be created. These are set with a call to the routine Asynch_Set_Peakflow_Output.

The routines for setting custom outputs are described below.

int Asynch_Set_Output_Int(AsynchSolver *asynch, char *name, OutputIntCallback *callback, unsigned int *used_states, unsigned int num_states)

This routine sets a custom output time series.

A function is required that will be called every time output data is to be written for a link. The function set in this routine should have the specification Asynch_Set_Output_Int must also be given an array used_states. This array contains the indices of the states in the state vectors which are needed by the user specified routine callback. All states listed in this array are guaranteed to be available for the routine callback.

See also

Asynch_Set_Output_Double

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • name – Name of the custom time series.

  • callback – Routine to call when writing data for the custom output.

  • used_states – Array of the all indices in the state vector used by callback.

  • num_states – Numver of indiciced in used_states.

int Asynch_Set_Output_Double(AsynchSolver *asynch, char *name, OutputDoubleCallback *callback, unsigned int *used_states, unsigned int num_states)

This routine sets a custom output time series.

A function is required that will be called every time output data is to be written for a link. The function set in this routine should have the specification Asynch_Set_Output_Double must also be given an array used_states. This array contains the indices of the states in the state vectors which are needed by the user specified routine callback. All states listed in this array are guaranteed to be available for the routine callback.

See also

Asynch_Set_Output_Int

Parameters:
  • asynch – A pointer to a AsynchSolver object to use.

  • name – Name of the custom time series.

  • callback – Routine to call when writing data for the custom output.

  • used_states – Array of the all indices in the state vector used by callback.

  • num_states – Numver of indiciced in used_states.

Interface for other languages (asynch_api.h)

asynch_api.h complements the routines above for programs in other languages (the Python package uses it) and for tests. It exchanges only numbers, arrays and opaque pointers, never the layout of an internal structure, and designates a link by its location (0 to N-1). It also describes custom models without C structures: a model specification (AsynchModelSpec) gathers the sizes, the equation functions and the options, and Asynch_Install_Model gives it to a solver before the global file is read.

Additional C interface of ASYNCH, designed for other languages (the Python package in python/) and for tests.

It complements asynch_interface.h with two rules:

  • only plain types, arrays and opaque handles are exchanged: a caller never needs to know the layout of an internal structure (Link, GlobalVars, …), so it cannot get out of sync with it;

  • a link is designated by its location, 0 .. N-1, the index used everywhere inside ASYNCH; Asynch_Find_Link converts a link id (as in the .rvr file) to its location.

Functions marked collective must be called by every MPI process of the solver.

Typedefs

typedef struct AsynchModelSpec AsynchModelSpec

Opaque description of a model: sizes, equations and options.

typedef void SpecPrecalculationsFunc(const double *const global_params, unsigned int num_global_params, double *params, unsigned int num_params, void *user)

Derived parameters of one link.

params has num_params values; the first num_disk_params were read from the .prm file (after the conversion factors), the others are to be computed here.

typedef int SpecInitializeFunc(const double *const global_params, unsigned int num_global_params, const double *const params, unsigned int num_params, double *y, unsigned int dim, void *user)

Initial states of one link.

On entry, y holds the states read from the initial-state file (the first num_read states, see Asynch_Model_Spec_Set_Num_Initial_States) and 0 for the others. Returns the discontinuity state (0 if unused).

Functions

int Asynch_MPI_Init(void)

Initialises MPI if it is not initialised yet. Returns 1 if this call initialised it, 0 otherwise.

int Asynch_MPI_Finalize(void)

Finalises MPI if it is initialised and not finalised yet. Returns 1 if this call finalised it.

AsynchSolver *Asynch_Init_World(bool verbose)

Creates a solver on MPI_COMM_WORLD (MPI must be initialised, see Asynch_MPI_Init).

AsynchSolver *Asynch_Init_Fortran_Comm(int fortran_comm, bool verbose)

Creates a solver on the communicator given by its Fortran handle (with mpi4py: comm.py2f()).

int Asynch_Get_Rank(AsynchSolver *asynch)

Rank of this process in the solver’s communicator.

int Asynch_Get_Num_Procs(AsynchSolver *asynch)

Number of processes in the solver’s communicator.

Id (as in the .rvr file) of the link at location loc.

Location of the link with the given id, or -1 if there is no such link.

Rank of the process that computes the link at location loc (after partitioning), -1 before.

Number of upstream links (parents) of the link at location loc.

Writes the ids of the parents of the link at location loc into ids; returns their number.

Id of the downstream link (child) of the link at location loc, or -1 for an outlet.

Number of states of the link at location loc (after Asynch_Initialize_Model; 0 if not known here).

unsigned int Asynch_Get_Max_Dim(AsynchSolver *asynch)

Largest number of states of any link (after Asynch_Initialize_Model).

Number of parameters per link, including those computed by the precalculations.

unsigned int Asynch_Get_Num_Disk_Params(AsynchSolver *asynch)

Number of parameters per link read from the .prm file (or database).

Copies the parameters of the link at location loc into params (Asynch_Get_Num_Link_Params values).

Returns 0, or 1 if the parameters of this link are not stored on this process.

Sets the first n parameters of the link at location loc.

Returns 0, or 1 if the link is not stored on this process or n is too large. After changing parameters read from disk, call Asynch_Update_Precalculations so that the derived parameters follow.

int Asynch_Update_Precalculations(AsynchSolver *asynch)

Recomputes the derived link parameters (precalculations) from the current global and link parameters, e.g.

after Asynch_Set_Global_Parameters. Call after Asynch_Initialize_Model. Returns 0, or 1 if the model is not initialised yet.

double Asynch_Get_Current_Time(AsynchSolver *asynch)

Time reached by the solver [minutes since the start].

Latest state of the link at location loc (Asynch_Get_Link_Dim values) and its time [min].

Returns 0, or 1 if the link is not computed by this process.

int Asynch_Gather_States(AsynchSolver *asynch, double *states)

Collective.

Latest states of all links, on every process: states[loc * max_dim + k] is state k of the link at location loc (unused entries are 0). states must hold N * Asynch_Get_Max_Dim values.

int Asynch_Set_States(AsynchSolver *asynch, double t, const double *states)

Collective.

Sets the states of all links at time t [minutes since the start] and resets the solver there, so that Asynch_Advance continues from these states. states has the layout of Asynch_Gather_States. Returns 0.

int Asynch_Gather_Peakflows(AsynchSolver *asynch, double *peak_time, double *peak_value)

Collective.

Peak of state 0 (discharge) of every link since the start, and its time [min], on every process: peak_value[loc], peak_time[loc]. Links without peak output get 0. Returns 0.

unsigned int Asynch_Get_Num_Forcings(AsynchSolver *asynch)

Number of forcings of the model (rain, evaporation, …).

Current value of each forcing at the link at location loc. Returns 0, or 1 if not computed here.

AsynchModelSpec *Asynch_Model_Spec_Create(unsigned int num_states, unsigned int num_global_params, unsigned int num_params, unsigned int num_disk_params, unsigned int num_forcings)

Creates a model description.

num_disk_params <= num_params. Every other setting has a default: all states read from the initial file, dense output of state 0, no precalculations, no consistency check, no conversion of the .prm values. Returns NULL if a size is invalid.

void Asynch_Model_Spec_Free(AsynchModelSpec *spec)

Frees a model description (not while a solver still uses it).

int Asynch_Model_Spec_Set_Differential(AsynchModelSpec *spec, DifferentialFunc *func)

The right-hand side dy/dt (required).

Its user argument is the pointer set by Asynch_Model_Spec_Set_User.

int Asynch_Model_Spec_Set_Precalculations(AsynchModelSpec *spec, SpecPrecalculationsFunc *func)

Derived parameters (optional).

int Asynch_Model_Spec_Set_Initialize(AsynchModelSpec *spec, SpecInitializeFunc *func)

Initial states not read from file (optional).

int Asynch_Model_Spec_Set_Num_Initial_States(AsynchModelSpec *spec, unsigned int n)

Number of states read from the initial-state file (the first n; default: all).

int Asynch_Model_Spec_Set_Dense_Indices(AsynchModelSpec *spec, unsigned int n, const unsigned int *indices)

States interpolated for downstream links (default: {0}).

Every state used through y_p in the differential function must be listed.

int Asynch_Model_Spec_Set_Nonnegative(AsynchModelSpec *spec, int mode)

Built-in consistency check applied after every stage and step: 0 = none (default), 1 = every state >= 0, 2 = state 0 >= 1e-14 and every other state >= 0 (as models 190 and 254).

int Asynch_Model_Spec_Set_Check_Consistency(AsynchModelSpec *spec, CheckConsistencyFunc *func)

Custom consistency check (replaces the built-in one). Its user argument is the spec’s user pointer.

int Asynch_Model_Spec_Set_Param_Factors(AsynchModelSpec *spec, const double *factors)

Factors applied to the parameters read from disk (num_disk_params values), e.g. 1000 to convert km to m.

int Asynch_Model_Spec_Set_Areas(AsynchModelSpec *spec, unsigned int area_idx, unsigned int areah_idx, bool converted_to_m2)

Position of the upstream area and of the hillslope area in the link parameters (used by the peak output), and whether they were converted from km2 to m2 (then the peak output converts back).

int Asynch_Model_Spec_Set_Min_Error_Tolerances(AsynchModelSpec *spec, unsigned int n)

Minimum number of error tolerances per link in the global file (default: num_states).

int Asynch_Model_Spec_Set_User(AsynchModelSpec *spec, void *user)

Pointer passed as user to the model functions (default NULL).

int Asynch_Install_Model(AsynchSolver *asynch, AsynchModelSpec *spec)

Uses spec as the model of this solver, instead of the model number of the global file.

Must be called before Asynch_Parse_GBL. Returns 0, or 1 if the spec is incomplete.