Transcript
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 : Runoff

DataOperaiton : Distributed

ElementSet : Polygons

Quantity ID : Inflow

ElementSet : 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

access

access

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 water

Model

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.Spatial

ElementMapper

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, linkID=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

{unti l l QtoGW is stabi l ized}

«interface»

GroundWaterModel :

ILinkableComponent

«interface»

RiverModel :

ILinkableComponent

IterationControl ler

:

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}

User

MainProgram

:

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


Recommended