implementation steps
We will implement running of Sobek through a dll using the following approach:
Extend fortran code to allow for setting model parameters and data (ie "setvalues")
In C# the module wlacces implements running of sobek models that are defined in a file.
setvalues will be defined in new interface (not in iwlaccess !)
fortran c / code will implement methods in interface
Steps to follow
step 1
Convert cf_openmi to vs2005 sln (debugging fortran will be easier and is a requirement)
step 2
Define derived types for 1d model:
- Network
Type Network int nNodes Node Nodes [nNodes] int nBranches Branch Branches [] End Type Type Node End Type Type Branch End Type
- Model parameters
- Boundary Conditions
- Initial Conditions
- Structures
- Output variables
step 3
create an adapter inside cf_openmi with an interface to 1d model with at least the following kind of methods:
-setnetwork
-setboundaryandinitial
-setparameters
we want our c# model to look like this (user friendly)
[Test] public void RunSobek() { double startTime = 0.0; double endTime = 10.0; double timeStep = 1.0; Model1D.Initialize(); // create simple network // // n1 n2 n3 // x|----|--------|x|-------------|x // r1 r2 // Model1D.SetBranches(...); Model1D.SetGridSteps(...); Model1D.SetRunTimeParameter(startTime, endTime, timeStep); Model1D.RunTimeStep(); double time = Model1D.GetCurrentTime(); Assert.AreEqual(1.0, time); }
see similar implementation for modflow
examples
- MODFLOW wrapper example, checkout https://openmi.svn.sourceforge.net/svnroot/openmi/branches/OpenMI-1.4.1-dev and check MyOpenSource\Wrappers\src\USGS\MODFLOW.
- Existing SOBEK OpenMI wrapper: http://svn/repos/ds/trunk/previous/openmi_wrapper
Notes
- Sobek OpenMI module:
Useful function for initialising and performing one or more timesteps and finalizing.
-
- 'SE_OpenMI.f90' communicates with OEM buffer.
- 'SE_OpenMI.f90' has calls to module OMI_CF_control in (OMI_CF_control.f90), which in turn calls directly sobeksim subroutines
- Present SOBEK reads nefis files during initialisation (using m_nefisinput.mod). Nefis is used in subroutines: read_initial_values_strpar_etc, soedef, sogetm and wetcrs.
SOBEK variables read from NEFIS
module DS_communication type Sobek_Data integer :: nnode ! nr of sobek nodes integer :: nbran ! nr of branches integer :: nstdb integer :: nstru ! number of structures integer :: ntrigr ! number of triggers integer :: ncontr ! number of controllers integer :: ntcrel ! number of trigger-controller relations integer :: ncsrel ! number of controller-structure relations integer :: nqlat ! number of lateral inflows integer :: ngrid ! nr of sobek points integer :: nboun ! number of open boundaries integer :: nhstat ! number of 1D waterlevel boundaries integer :: nqstat ! number of 1D discharge boundaries integer :: ntabm integer :: maxtab integer :: maxlev integer :: ncross integer :: nevents integer :: mxstrpar ! leading dimension of strpar integer :: mxistrtyp ! leading dimension of istrtyp integer :: mxstrmu ! integer :: mxcross integer :: mxqltpar integer :: mxtriger ! leading dimension of triger integer :: mxcontrl ! leading dimension of contrl integer :: mxconhis = 5 ! leading dimension of conhis integer :: mxconhis ! leading dimension of conhis integer :: mxtrcnrl ! leading dimension of trcnrl integer :: mxcnstrl ! leading dimension of cnstrl = 2 integer :: mxengpar ! dimension of engpar integer :: mxbranch ! lead dim of branch integer :: nupt integer :: msect integer :: lcnvmax real , allocatable :: strpar (:,:) ! structure parameters (mxstrpar,nstru) real , allocatable :: strmu (:,:) ! structure mu (mxstrmu,nstru) integer, allocatable :: istrtyp(:,:) ! structure type (mxistrtyp,nstru) character(len=40), allocatable :: contrnam(:) ! names of controllers (ncontr) character(len=40), allocatable :: trigrnam(:) ! names of triggers (ntrigr) character(len=40), allocatable :: qlatnm(:) ! ids of qlats (nqlat) real , allocatable :: qlat (:) ! lateral inflow (nqlat) real , allocatable :: qltpar(:,:) ! lateral inflow parameters (mxqltpar,nqlat) integer, allocatable :: node(:,:) ! sobek node administration (nnode) integer, allocatable :: branch(:,:) ! sobek branch admin (mxbranch,nbran) integer, allocatable :: triger(:,:) ! trigger data (mxtriger,ntrigr) real , allocatable :: contrl(:,:) ! controller data (mxcontrl,ncontr) integer, allocatable :: trcnrl(:,:) ! trigger controller relation (mxtrcnrl,ntcrel) integer, allocatable :: cnstrl(:,:) ! controller structure relation (mxcnstrl,ncsrel) integer, allocatable :: hbdpar(:,:) ! integer parameters (3,*), 1=?, 2=iopt, 3=itab (3,nhstat) integer, allocatable :: qbdpar(:,:) ! integer parameters (3,*), 1=?, 2=iopt, 3=itab (3,nqstat) real , allocatable :: engpar(:) ! Engelund-Hansen parameters (mxengpar) real , allocatable :: hpack(:) ! s0 voor sobek points (ngrid) real , allocatable :: qpack(:) ! q voor sobek points (ngrid) double precision, allocatable :: xycoor(:,:) ! (2,ngrid) x,y coordinates for sobek points (2,ngrid) integer, allocatable :: nlevu (:) ! (nupt) real, allocatable :: chan_hu (:,:) ! (ngrid) real, allocatable :: chan_af (:,:,:) ! (nupt,lcnvmax,msect) real, allocatable :: chan_wf (:,:,:) ! (nupt,lcnvmax,msect) real, allocatable :: chan_pf (:,:,:) ! (nupt,lcnvmax,msect) real, allocatable :: chan_co (:,:,:) ! (nupt,lcnvmax,msect) real, allocatable :: chan_cn (:,:,:) ! (nupt,lcnvmax,msect) real, allocatable :: chan_cz1(:,:,:) ! (nupt,lcnvmax,msect) real, allocatable :: chan_cz2(:,:,:) ! (nupt,lcnvmax,msect) integer, allocatable :: nlevh (:) ! (nupt,lcnvmax,msect) real, allocatable :: chan_hh (:,:) ! (ngrid,lcnvmax) real, allocatable :: chan_at (:,:) ! (ngrid,lcnvmax) real, allocatable :: chan_wt (:,:) ! (ngrid,lcnvmax) character(len=CharLen ), allocatable, save :: nodenm ! (nnode) character(len=CharLen ), allocatable, save :: gridnnm ! (ngrid) end type Sobek_Data end module