15
Programmer’s guide for Waqua as a component in OpenMI SIMONA report number 2009-02

Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide for Waqua as acomponent in OpenMI

SIMONA report number 2009-02

Page 2: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide OpenMI-component Waqua

2

Page 3: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide for Waqua as acomponent in OpenMI

Version number : Version 1.1, March 2010Maintenance : see www.helpdeskwater.nl/waquaCopyright : Rijkswaterstaat

Page 4: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide OpenMI-component Waqua

Log-sheet

Version Author Date Description

1.0 VORtech 09-06-2009 c88648: initial version

1.1 E.J. Spee 30-03-2010 c1379: description of keepgo = 2

File location: bo_omgeving/simona/src/waqua/waqomi/doc/sysdoc

4

Page 5: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

CONTENTS

Contents

Log-sheet 4

1 Introduction 6

2 Technical documentation of the Waqua OpenMI component 7

2.1 Overview of the structure of the Waqua component . . . . . . . . . . . . . . . . . 7

2.2 Exchange items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.3 Interface routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

A Changes to the previously existing SIMONA software 11

A.1 Changes to SIMONA’s make system . . . . . . . . . . . . . . . . . . . . . . . . . 11

A.2 Changes to Waqpro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

A.3 Changes to SIMONA’s tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Version 1.1, March 2010 5

Page 6: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide OpenMI-component Waqua

Chapter 1

Introduction

Deltares participed in the 3-years European project called “OpenMI-Life”. This is a demonstrationproject for OpenMI which is a standard that allows time-dependent models to exchange data at run-time. Using this standard, existing models, even those of different institutions, can be run togetherand exchange information at each timestep.

Two flow models of a different structure, each describing a separate region, from two differentorganisations can now be coupled. The first model is called “Kust-Zuid”, and is run using theWaqua software, owned by the Dutch Rijkswaterstaat. It covers the Dutch part of the Schelde basin.The other model describes the flow in the Flemish part of the Schelde basin and is run using Mike11,a software package by the Danish Hydrological Institute (DHI).

Besides the coupling between Waqua and Mike11, OpenMI is also used to couple Waqua with thewave model Swan.

The purpose of this document is reporting on the activities performed in order to make Waqua“OpenMI-compliant”. Chapter 2 describes the software that was developed in order to make itpossible to use a Waqua model as a component. The changes which had to be made to the existingSIMONA system are described in Appendix A.

6

Page 7: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Chapter 2. Technical documentation of the Waqua OpenMI component

Chapter 2

Technical documentation of the WaquaOpenMI component

In this chapter we document the work that has been done to allow Waqua to be used as a componentin an OpenMI system.

2.1 Overview of the structure of the Waqua component

Components of an OpenMI-system often consist of two parts: the so-called wrapper and the so-called model core or engine. OpenMI then communicates only with the wrappers and the wrapperscommunicate with the engines for which they are made. The idea of wrappers and engines isillustrated in Figure 2.1. It has not been necessary to write a new wrapper for the OpenMI-compliantWaqua component, because the wrapper Deltares.OpenMI.Wrapper, made for the OpenMI-compliant components Delft3D and Sobek, has been used practically without any changes. Theonly change made to the wrapper was that the dynamically linked libary libwaqomi.dll wasadded to the list of libraries which can be used to make the engine. Like OpenMI itself, this genericwrapper of Deltares (formerly Deltares) is written in C#.

There is a fixed set of subroutines that is called by the wrapper Deltares.OpenMI.Wrapper.New implementations of these routines have been made for turning Waqua into an OpenMI compo-nent. These routines have been put in a new SIMONA subsystem called Waqomi. Some of theseroutines call Waqua-routines to perform their tasks. The Waqua-routines themselves are stored inSIMONA subsystem Waqpro. This is the actual model engine for the Waqua component. Thesubsystem Waqomi can be seen as a wrapper for this model engine that is written in Fortran, andthat is called by the generic Deltares-wrapper written in C#.

Some changes have had to be made to the SIMONA software in order to allow for the extension ofWaqua into an OpenMI-compliant component. These changes are described in the Appendix A.

In the coupled calculation of an OpenMI system, OpenMI requests the Waqua component to performcertain tasks. This is done by calling the routines of the Deltares.OpenMI.Wrapper, whichin turn calls the routines of Waqomi. The tasks asked from the Waqua component are (roughly):

Version 1.1, March 2010 7

Page 8: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide OpenMI-component Waqua

WLDelft.OpenMI.Wrapper(C#)

DHI.OpenMI.Wrapper

Mike11 enginemike11.dll

Mike11 Component

SinusInput Component OpenMI

ComponentWAQUA

waqomi

waqomi.dll

WAQUA engine

WAQUA wrapper

waqpro(fortran)

(fortran)

Figure 2.1: OpenMI components often consists of “wrappers” and a “model engine”. Communi-cation between components is done via OpenMI: every model engine communicates only with itsown wrapper; OpenMI communicates only with wrappers. Waqua components even have two wrap-pers, because the engine was fitted to an generic wrapper. Components which have been developedespecially for OpenMI, such as the SinusInput components, have no wrappers.

8

Page 9: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Chapter 2. Technical documentation of the Waqua OpenMI component

• OpenMI asks the component to initialize itself.

It calls the routine se_Initialize.

• OpenMI asks the component which exchange items exist for incoming and outgoing informa-tion exchange with OpenMI.

It calls the routines CanAcceptOnSet and/or CanProvideOnSet.

• For all the exchange items, OpenMI asks the dimension of the coupled data, so it can checkthat this dimension matches that of the coupled item from another component.

It calls the routine se_GetValuesElementCounts.

• In a loop, time steps are taken and values are exchanged between the exchange items and theircoupled counterparts in other models.

OpenMI calls the routines se_PerformTimeStep, se_SetValues and se_GetValues.

• OpenMI asks the component to finish its activities.

It calls the routine se_Finalize.

A complete list of the subroutines called by the wrapper is given at the end of this section. Many ofthese subroutines are very small and simple.

2.2 Exchange items

Exchange items are representations of those things in Waqua which may be coupled to a corre-sponding item in a different OpenMI-compliant component, e.g. boundary and discharge values asinput and flow history data as output.

In the communication between the Waqua component and the wrapper, the wrapper must make itclear exactly which exchange item the wrapper is asking about. The main tool for the identificationof an exchange item is its name. Within Waqomi the data for exchange items is stored in a structarray Eitem and the names correspond to the field ID.

It is possible, however, that there are multiple exchange items with the same name. Two exchangeitems with the same name can still be distinguished if their quantity is different (field quantity, astring). Two exchange items with the same name and quantity may even still be distinguished if oneexchange item is only intended for providing information to OpenMI, and the other for acceptinginformation from OpenMI (field role, with possible values providing and accepting).

There is one exception to these rules. When the generic wrapper asks the dimension of the data(routine se_GetValuesElementCounts), the question refers to all the exchange items of acertain name. Therefore, the data of all the exchange items with the same name (whatever theirquantity and whether providing or accepting) must have the same dimension. A simple way tounderstand this rule is by realizing that the name of the exchange item refers to its location (a point,a grid, a curve, etcetera). Whatever the quantity represented on this location, and whether it is inputor output, it will have the same dimension.

Version 1.1, March 2010 9

Page 10: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide OpenMI-component Waqua

A large number of exchange items are created in the initialization phase of the Waqua component,most of which will not be used in an actual coupling. Their names (ID’s) are created from the input,so in certain cases it may be necessary to change the input names of openings, discharge sources,checkpoints etcetera in the input for the Waqua model, to avoid confusion when coupling a modelto other models using OpenMI.

The exchange items are created at the end of the initialization process, in routine se_Initiali-ze). This is done by the routine waqomi_create_exchange_items, called by se_Initialize.The exchange items created by this routine are listed in the user manual of the OpenMI componentWaqua.

2.3 Interface routines

The following routines are called by the generic wrapper and provided by the specific wrapperWaqomi:

• GetArgumentStringLength - return length of strings used in Waqomi

• Routines concerning Waqpro’s time line:

– SE_GetTimeHorizon, SE_GetCurrentTime, SE_GetInputTime

• Routines which activate large parts of the “engine”:

– SE_Initialize, SE_PerformTimeStep, SE_Finalize

• Routines concerning the quantities used:

– GetQuantityCount, GetQuantity

• Routines concerning Element Sets and Elements. Note that each element set has one element:an exchange item.

– GetElementSetCount, GetElementset

– CanAcceptOnSet, CanProvideOnSet

– SE_GetValuesElementCount - return dimension of values

– SE_SetValues = SE_SetValuesAtTime - set the values of a given exchange item

– SE_GetValues - return the values of a given exchange item

– GetElementInSetCount - number of elements in element set (always 1)

– GetElementInSet - return an element of a set (always same as element)

• Routines for things which are not currently supported in the Waqua component. These rou-tines either return the value UNDEFINED or the value zero.

– GetElementTypeCount, GetElementType, KeepCurrentState, RestoreState,ClearState, GetElementInSetVertexCount, GetElementInSetCoordinate

10

Page 11: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Appendix A. Changes to the previously existing SIMONA software

Appendix A

Changes to the previously existing SIMONAsoftware

A.1 Changes to SIMONA’s make system

The system OpenMI needs a dynamically linked library (dll) for its coupling to Waqua. When thecoupling between Waqua and Costa was made, a temporary facility for the creation of dll’s wascreated in the form of a script make_waqcta_so.pl, which was to be run after every change inWaqua or the coupling system waqcosta.

In the present change, a more permanent solution has been made for SIMONA subsystems whosetargets include a dll such as Waqomi, the subsystem for coupling Waqua and OpenMI. This hasbeen done in the following way.

The subroutines which have to be included in the dll are placed in the routines-directory. Apartfrom these subroutines, a subroutine is written with the special name <subsystem>_dll.f.This special subroutine must contain calls to all the user routines: those subroutines which have tobe available in the dll file. It is not necessary that it is possible to call the special subroutine; thefact that calls to the user routines exist in the main subroutine causes them to be included in the dll.Besides the routines called in the “main” subroutine, also all the routines needed by them, as wellthose that belong to the current SIMONA subsystem and those that belong to any of the SIMONAsubsystems used by the current one, are also included in the dll.

Processing the routines-directory in this way is very similar to the way in which the routines-directory handles a main program: all the available files are compiled into object files and collectedinto a library-file. When the library file is complete, it is used to link with a “main” source file intothe final target file.

The difference between the creation of an executable and a dll is in the details of the linkingstep. When creating an executable, the central source file used in linking is the main program,and the final target file is an executable file. In the case of a dll, the final target file is the dlllib<subsystem>.dll (Windows) or lib<subsystem>.so (Linux).

Version 1.1, March 2010 11

Page 12: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide OpenMI-component Waqua

A.2 Changes to Waqpro

The following changes have been made to the original code of the waqpro system:

• Parts of the main program waqpro have been moved to new routines waspri, wasarg andwaspre.

All three of these routines contain initializations. The routines waspri and waspre are alsoused by the OpenMI-compliant Waqua-component, but the routine wasarg is not.

During the analysis of the main program, it was noted that the existing routine wascip hasmany unused header variables. These have been removed.

The changes in the structure of the waqpro-initializations have led to similar changes inroutine cwqini, the initializations in the interface between Waqua and Costa.

• Some statements in the finalizing phase of the Waqua run have been moved from the mainprogram waqpro to the (existing) routine waspos. This led to a similar change in the routinecwqfri, the finalization in the interface between Waqua and Costa.

• The flag iopnmi has been added to the intgda-table at location intgda(169,1). Thisflag has the value 1 when the software is being used as an OpenMI-compliant component, andit has the value 0 when it is used outside of OpenMI.

The value 0 is set by the main program waqpro, because the main program is only usedwhen the software is used outside OpenMI.

• One of the tasks of the initialization routine wasins is to redirect the standard output file(file unit number irefwr) to the correct message file. This is only necessary in case ofcoupled runs. Hence, when the software is running as an OpenMI component (and is thereforecoupled), the message file must be set.

• The information passed from OpenMI to the Waqua Component has to be entered into Waqua’sdata structures. This concerns the type of information known as “forcings” in Waqua. Thedata structures for these forcings are available in the routine wassff. Therefore, this rou-tine must be extended with a call to the routine waqomi_set_forcings, which sets theforcings provided by OpenMI.

This call poses a problem in terms of software design: the Waqua routines are not only usedby the interface routines in the new SIMONA Subsystem waqomi, but the Waqua routinewassff also calls a waqomi-routine: a circular dependence which causes a problem whenlinking the dll and the executable.

The solution chosen is that initialization of the OpenMI-compliant Waqua-component in-cludes setting an subroutine pointer in the intgda-table. Only when running as an OpenMIcomponent is this subroutine pointer looked up and activated by the routine wassff. Thissolution has required the introduction of certain facilities for the manipulation and use ofsubroutine pointers in the SIMONA Tools, described in Section A.3.

12

Page 13: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Appendix A. Changes to the previously existing SIMONA software

A.3 Changes to SIMONA’s tools

Disallowing SIMONA to exit

In OpenMI, a component should never exit the program. Since exiting a SIMONA program isalways done by calling siexit (through sistop), it was simple to introduce the flag keepgo inthe common block csierr. Setting this flag disables the call to exit in siexit. The flag is set(to zero) by sistar, after which it may be reset (to one) by the program that runs in SIMONA.The flag keepgo can also be set to two. In that case, calling siexit will throw an exception.This is usefull during PerformTimeStep and Initialize where some unexpected error mayoccur. The exception will be caught by the (C#)-wrapper.

Checking that file units are free

Almost all files opened by SIMONA programs are opened using siflop or other SIMONA sub-routines, which check that the file unit number is not used. Only in a few cases, mostly in thestart-up process of the SIMONA environment, a file unit was chosen without such a check. The newfunction siflun has been introduced in order to avoid conflicts between a Waqua component andother components written in Fortran. This new function returns an unused file unit number.

Starting SIMONA without work directory

In the context of OpenMI simulations, it is not practical to work with a work directory, such as isusually done by SIMONA-software. The work directory contains the SIMONA environment file,the SIMONA Error Text File and the syntax description of debug input files (nmdbgref.arr).

The use of the work directory has been avoided in the Waqua component for OpenMI by readingthe necessary files from the local directory, if these files exist, and reading them directly from theSIMONA installation if they don’t exist locally.

A new common block, by the name of csifil, has been introduced. The subroutine sirdcf,which is called before sistar, clears the variables simetf and simenv, which are the namesof the SIMONA error text file and the SIMONA environment file.

If the program sets these file names before the program calls sistar, the usual file names areoverruled in the initialization of SIMONA.

Subroutine pointers in SIMONA

There is one waqomi-subroutine, waqomi_set_forcings_header, which is called from theWaqua-routine wassff. A direct call to this routine from Waqua would make Waqua depend on thenew subsystem waqomi. However, this subsystem depends on Waqua itself. The following solutionhas been constructed to avoid a complicated dependence structure of the SIMONA subsystems.

In the initialization phase of the OpenMI-compliant Waqua component, a pointer to the routinewaqomi_set_forcings_header is stored in the intgda-table, the table where a lot of gen-

Version 1.1, March 2010 13

Page 14: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Programmer’s guide OpenMI-component Waqua

eral information for waqpro is stored. The routine wassff can read from the flag iopnmi (alsostored in intgda) whether Waqua is running as an OpenMI-component or not. In case that this isso, the pointer to waqomi_set_forcings_header is looked up so the routine may be called.When Waqua is not running inside OpenMI, the routine is not known and not needed.

The use of subroutine pointers is facilitated by the following new subroutines in the SIMONAsubsystem tools:

• sipntr: Return an integer representing the pointer to a subroutine.

• sirout: Call the subroutine indicated by the given pointer, using the arguments preparedusing calls to sinarg and/or sisarg.

The list of arguments is cleared so the argument list for the next call can be set up.

• sinarg: Add a non-string argument to the list of subroutine arguments for the next call.

• sisarg: Add a string argument to the list of subroutine arguments for the next call.

The possibilities of the subroutine pointers are illustrated by the sample program in Table A.1.

14

Page 15: Programmer's guide for Waqua as a component in OpenMIsimona.deltares.nl/release/doc/sysdoc/waqomi/waqomi-sysdoc.pdf · Introduction Deltares participed in the 3-years European project

Appendix A. Changes to the previously existing SIMONA software

c Declarationsc

external my_routinecharacter*(*) text1, line, name1integer m,n, tabel(m,n), ihrout, ilendouble precision pi

cc Functions usedc

integer sipntrcc Get the pointer to the routinec

ihrout = sipntr(my_routine)cc Build the argument listc

call sisarg(text, name1(1:ilen))call sinarg(n, name1(1:ilen))call sinarg(m, name1(1:ilen))call sisarg(line, name1(1:ilen))call sinarg(tabel, name1(1:ilen))call sinarg(pi, name1(1:ilen))

cc call my_routine(text,n,m,name1,tabel,pi)c

call sirout(ihrout)

Table A.1: Sample code for the illustration of the use of subroutine pointers with the SIMONA-tools.

Version 1.1, March 2010 15