40
Jan Gregersen 1 Jan Gregersen http://www.LicTek.com OpenMI Developers Training

OpenMI Developers Training

Embed Size (px)

DESCRIPTION

Introduction to developing or migrating models to be compliant to the OpenMI Standard. OpenMI is an open standard which allows dynamic linking of numerical models, such as river models rainfall-runoff models and so on. See also:http://www.lictek.com

Citation preview

Page 1: OpenMI Developers Training

Jan Gregersen 1

Jan Gregersen

http://www.LicTek.com

OpenMI Developers Training

Page 2: OpenMI Developers Training

Jan Gregersen 2

Simple River

5 10

X (km)

Y (km)

5

10 Node:0

Node:1

Node:2

Node:3

Branch:0

Branch:1

Branch:2

Y (km) 5 10

X (km)

5

10

Runoff Model

Simple River

OutputExchangeItem InputExchangeItem

Quantity ID : RunoffDataOperaiton : DistributedElementSet : Polygons

Quantity ID : InflowElementSet : Polyline

Page 3: OpenMI Developers Training

Jan Gregersen 3

How it works

Load components:

Query exchange items:

Add links:

Page 4: OpenMI Developers Training

Jan Gregersen 4

How it works

Prepare:

Run (GetValues):

Finish:

Page 5: OpenMI Developers Training

DHI - Water & Environment Jan Gregersen

The OpenMI standard

Page 6: OpenMI Developers Training

Jan Gregersen 6

Page 7: OpenMI Developers Training

DHI - Water & Environment Jan Gregersen

Migration of models

Page 8: OpenMI Developers Training

Jan Gregersen 8

Now What ???

Page 9: OpenMI Developers Training

Jan Gregersen 9

Org.OpenMI.Utilities

Org.OpenMI.Utilities.Spatial

Org.OpenMI.Utilities.Buffer

Org.OpenMI.Utilities.Wrapper

Buffers results from the engine core

Mapping of values associated to one array of times /timespans to values represented on another array of times/timespans

t t

Mapping of values associated to one ElementSet to be represented on another ElementSet

SmartBuffer

ElementMapper

SmartWrapper

Generic wrapper suited for time stepping model engines

Page 10: OpenMI Developers Training

Jan Gregersen 10

LinkableEngine features

• Provides a default implementation of the ILinkableComponent interface

• Links bookkeeping• Event handling• Buffering• Temporal interpolations, aggregations,

extrapolations• Spatial interpolations, aggregations,

extrapolations

Page 11: OpenMI Developers Training

Jan Gregersen 11

Wrapper design pattern

Page 12: OpenMI Developers Training

Jan Gregersen 12

IEngine Interface

// -- Execution control methods (Inherited from IRunEngine) --void Initialize(Hashtable properties);

bool PerformTimeStep();

void Finish();

//-- Time methods (Inherited from IRunEngine) --ITime GetCurrentTime();

ITime GetInputTime(string QuantityID, string ElementSetID);

ITimeStamp GetEarliestNeededTime();

//-- Data access methods (Inherited from IRunEngine) --void SetValues(string QuantityID, string ElementSetID, IValueSet values);

IValueSet GetValues(string QuantityID, string ElementSetID);

//-- Component description methods (Inherited from IRunEngine) --double GetMissingValueDefinition();

string GetComponentID();

string GetComponentDescription();

// -- Model description methods --string GetModelID();

string GetModelDescription();

double GetTimeHorizon();

// -- Exchange items --int GetInputExchangeItemCount();

int GetOutputExchangeItemCount();

org.OpenMI.Backbone GetInputExchangeItem(int exchangeItemIndex);

org.OpenMI.Backbone GetOutputExchangeItem(int exchangeItemIndex);

Page 13: OpenMI Developers Training

Jan Gregersen 13

Inside the LinkableEngine

SmartWrapper

SmartInputLinkSet SmartOutputLinkSet

SmartInputLink

UpdateBuffer()GetValues()

UpdateInput()

SmartOutputLink

UpdateInput() UpdateBuffer()GetValues()

Link

SmartBuffer ElementMapper

*

1

*

1

has has

hashas

has

has

Link

accessaccess

Page 14: OpenMI Developers Training

Jan Gregersen 14

GetValues()

Model B Model A

GetValues(time, LinkID)

1. Update with input from linked models

2. Perform time step and fill internal buffers

3. Map values in time and space

Return values

While (CurrentTime < time & State is “Not Busy”)

GetValues(time, LinkID)

Page 15: OpenMI Developers Training

Jan Gregersen 15

GetValues()

Model B Model A

GetValues(time, LinkID)

1. Update with input from linked models

2. Perform time step and fill internal buffers

3. Map values in time and space

Return values

While (CurrentTime < time & State is “Not Busy”)

GetValues(time, LinkID)

Page 16: OpenMI Developers Training

Jan Gregersen 16

GetValues()

Model B Model AEngine

AIPAccess

SmartOutputLInkSet

A SmartBuffer

AElementMapper

A SmartOutput

LInk

SmartInputLink

Set

GetValues(tl LinkID)

GetCurrentTime()

IsBusy = true

A SmartInputLink

UpdateInput(ct)

UpdateInput(ct)GetValues(ct,LinkID)

SetValues(Quantity,LocationID,Values)

For each Input Link

Page 17: OpenMI Developers Training

Jan Gregersen 17

GetValues()

Model B Model A

GetValues(time, LinkID)

1. Update with input from linked models

2. Perform time step and fill internal buffers

3. Map values in time and space

Return values

While (CurrentTime < time & State is “Not Busy”)

GetValues(time, LinkID)

Page 18: OpenMI Developers Training

Jan Gregersen 18

GetValues()

Model B Model AEngine

AIPAccess

SmartOutputLInkSet

A SmartBuffer

AElementMapper

A SmartOutput

LInk

SmartInputLink

Set

PerformTimeStep()

A SmartInputLink

UpdateBuffers()

UpdateBuffer()

Getvalues(Quantity,LocationIDs)

Addvalues(time, valueSet)

For each output link

IsBusy = false

Page 19: OpenMI Developers Training

Jan Gregersen 19

GetValues()

Model B Model A

GetValues(time, LinkID)

1. Update with input from linked models

2. Perform time step and fill internal buffers

3. Map values in time and space

Return values

While (CurrentTime < time & State is “Not Busy”)

GetValues(time, LinkID)

Page 20: OpenMI Developers Training

Jan Gregersen 20

GetValues()

Model B Model AEngine

AIPAccess

SmartOutputLInkSet

A SmartBuffer

AElementMapper

A SmartOutput

LInk

SmartInputLink

Set

GetValues(time, LinkID)

A SmartInputLink

GetValues(time)

GetValues(time)

MapValues(inpuValues)

Page 21: OpenMI Developers Training

Jan Gregersen 21

IEngine Interface

// -- Execution control methods (Inherited from IRunEngine) --void Initialize(Hashtable properties);

bool PerformTimeStep();

void Finish();

//-- Time methods (Inherited from IRunEngine) --ITime GetCurrentTime();

ITime GetInputTime(string QuantityID, string ElementSetID);

ITimeStamp GetEarliestNeededTime();

//-- Data access methods (Inherited from IRunEngine) --void SetValues(string QuantityID, string ElementSetID, IValueSet values);

IValueSet GetValues(string QuantityID, string ElementSetID);

//-- Component description methods (Inherited from IRunEngine) --double GetMissingValueDefinition();

string GetComponentID();

string GetComponentDescription();

// -- Model description methods --string GetModelID();

string GetModelDescription();

double GetTimeHorizon();

// -- Exchange items --int GetInputExchangeItemCount();

int GetOutputExchangeItemCount();

org.OpenMI.Backbone GetInputExchangeItem(int exchangeItemIndex);

org.OpenMI.Backbone GetOutputExchangeItem(int exchangeItemIndex);

Page 22: OpenMI Developers Training

Jan Gregersen 22

Wrapper design pattern

Page 23: OpenMI Developers Training

Jan Gregersen 23

Migration steps

• Change your engine to a dll• Implement Initialize,

PerformTimeStep and Finish• Create the EngineDllWrapper class

Page 24: OpenMI Developers Training

Jan Gregersen 24

Wrapper design pattern

Page 25: OpenMI Developers Training

Jan Gregersen 25

Migration steps

• Create your MyEnigneWrapper• Implement Initialize and Finish• Implement remaining Ienigne

methods

Page 26: OpenMI Developers Training

Jan Gregersen 26

Page 27: OpenMI Developers Training

Jan Gregersen 27

The ElementMapper

Ground waterModel

River Model

GetValues(time, link)

CalculateReturn values

Link

ElementSetQuantity

“GW Recharge”

Has Has

Page 28: OpenMI Developers Training

Jan Gregersen 28

Spatial mapping

Page 29: OpenMI Developers Training

Jan Gregersen 29

ElementMapper

Org.OpenMI.Utilties.SpatialElementMapper

Initialise(string methodDescription, IElementSet fromElements, IElementSet toElements)IValueSet MapValues(IValueSet inputValues)

nmnmmm

n

n

n

m x

x

x

x

mmmm

mmmm

mmmm

mmmm

r

r

r

r

.

.

.....

.

.

.

.3

2

1

321

3333231

2232221

1131211

3

2

1

Page 30: OpenMI Developers Training

Jan Gregersen 30

Element Mapping

GE1GE2

GE3GE4

RE1

RE1

RE3

2/100

000

2/13/20

03/11

A

ALI

Page 31: OpenMI Developers Training

Element

• ID Based

• Point

• Line

• Polyline

• Polygon

“Node127”

(x1,y1)

(x1,y1) (x2,y2)

(x1,y1) (x2,y2) (x3,y3) (x4,y4)

(x1,y1)

(x2,y2)

(x3,y3)

(x4,y4)

(x5,y5)

Page 32: OpenMI Developers Training

ElementSet example

H

H

HH

H

H

H

H

H

H

H

HQ

Q

Q

Q

Q

Q

Q

Q

Q

Q

Q

Page 33: OpenMI Developers Training

Quantity

• ID ( “Runoff” )• Description ( “Rainfall runoff” )• Dimension ( e.g. L3 T-1 )

– GetPower ( <dimensionBase> )

• Unit:– ID ( “CFS” )– Descr ( “Cubic feet per second “ )– ConversionFactorToSI ( 0,0283168439

)– OffsetToSI ( 0 )

Page 34: OpenMI Developers Training

ExchangeItem

• InputExchangeItem– Quantity– ElementSet

• OutputExchangeItem– Quantity– ElementSet– [ DataOperations

• ID

• Arguments ]

Page 35: OpenMI Developers Training

Unidirectional link

{while RMtime < t1}

{while RRtime < RMtime + _dt}

«interface»

RRmodel :ILinkableComponent

«interface»

RiverModel :ILinkableComponentMainProgram

[1]

[2]

[3]

GetValues(time=t1, linkID=TriggerLink)

GetValues(time=RMtime + _dt, l inkID=RRtoRiver)

PerformTimeStep

return ValueSet: Runoff

PerformTimeStep

return ValueSet: RiverFlow

Page 36: OpenMI Developers Training

Bidirectional links

MainProgram

«interface»

RiverModel :ILinkableComponent

«interface»

GroundWaterModel :ILinkableComponent

RiverModel uses time step t1, GroundwaterModel uses time step t2

[2]

[3]

[6]

[7]

[1]

[4]

[5]

GetValues(t2,TriggerLink)

GetValues(time=t1, linkID=QtoRiver)

GetValues(time=t2, linkID=HtoGW)

Extrapolate (t2)

return extrapolated ValueSet: HtoGW (t2)

PerformTimeStep (t2)

return interpolated ValueSet QtoRiver (t1)

PerformTimeStep (t1)

GetValues(time=t2, linkID=QtoRiver)

return ValueSet QtoRiver (t2)

PerformTimeStep (t2)

return ValueSet Hriver (t2)

Page 37: OpenMI Developers Training

{until l QtoGW is stabil ized}

«interface»

GroundWaterModel :ILinkableComponent

«interface»

RiverModel :ILinkableComponent

IterationController :

ILinkableComponentMainProgram

[1]

[2]

[3]

[4]

[5]

[6]

[7]

GetValues(time=t2, l inkID=H_SW)

KeepCurrentState

RiverState_t_begin

KeepCurrentState

GWState_t_begin

InitialGuess(QtoGW)

RestoreState(RiverState_t_begin)

RestoreState(GWState_t_begin)

GetValues(time=t2, l inkID=H_GW)

GetValues(time=t2, l inkID=QtoGW)

QtoGW_guess

H_GW

GetValues(time=t2, l inkID=H_SW)

GetValues(time=t2, l inkID=QtoGW)

QtoGW_guess

H_SW

Evaluate

NewGuess(QtoGW)

result: H_SW

Page 38: OpenMI Developers Training

{until RRtime=t1}

UserMainProgram

:IListener

«interface»

RR model :ILinkableComponent

«interface»

RiverModel :ILinkableComponent

[1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

Start

GetValues(time=t1,TriggerLinkID)

OnEvent(SourceAfterGetValuesCall)

return computation thread

GetValues(time=t1,linkID=QtoRiver)

OnEvent(SourceAfterGetValuesCall)

return computation thread

PerformTimeStep((_dt))

OnEvent(DataChanged)

return computation thread

OnEvent(SourceBeforeGetValuesReturn)Pause

Resume

return computation thread

return ValueSet(QtoRiver, t1)

OnEvent(TargetAfterGetValuesReturn)

return computation thread

PerformTimeStep(RM_dt)

OnEvent(DataChanged)

OnEvent(SourceBeforeGetValuesReturn)

return computation thead

return ValueSet(t1)

Page 39: OpenMI Developers Training

Persistency

• OMI File– For identifying a linkable component

• Composition– In org.OpenMI.Utilities.Configuration– Holds administration of links and

linkable components– Can be run– Can be written and read to / from xml

Page 40: OpenMI Developers Training

Exercise 9:Unit Conversion

Step 1

Open the DataCombinator

Step 2

Adjust the code of GetValues so that it delivers data in the right unit

Step 3

Adjust the test program to ask for a quantity which has a conversion factor not equal to one

Step 4

Identify a value as missing value (e.g. -999) and adjust the input. Make sure this value is processed correctly.

Step 5

Test the program using NUnit