private void AddExchangeItem(string inOrOut, string inputItemId)
        {
            string[] quantAndElementSet = inputItemId.Split('.');
            if (quantAndElementSet.Length != 2)
            {
                throw new Exception("No \".\" specified in \"" + inputItemId + "\"" + ", component " + Id);
            }
            string elementSetId = quantAndElementSet[0];
            string quantId      = quantAndElementSet[1];

            if (!_quantities.ContainsKey(quantId))
            {
                throw new Exception("Quantity \"" + quantId + "\" does not exist in component " + Id);
            }
            if (!_elementSets.ContainsKey(elementSetId))
            {
                throw new Exception("ElementSet \"" + elementSetId + "\" does not exist in component " + Id);
            }

            if (inOrOut.Equals("inputitem"))
            {
                foreach (EngineInputItem inputItem in EngineInputItems)
                {
                    if (inputItem.Id.Equals(inputItemId))
                    {
                        throw new Exception("InputItem \"" + inputItemId + "\" already exists in component " + Id);
                    }
                }

                EngineInputItem newInputItem = new InputItem(inputItemId, _quantities[quantId],
                                                             _elementSets[elementSetId], this);
                newInputItem.StoreValuesInExchangeItem = true;
                EngineInputItems.Add(newInputItem);
            }
            else if (inOrOut.Equals("outputitem"))
            {
                foreach (EngineOutputItem outputItem in EngineOutputItems)
                {
                    if (outputItem.Id.Equals(inputItemId))
                    {
                        throw new Exception("OutputItem \"" + inputItemId + "\" already exists in component " + Id);
                    }
                }
                EngineOutputItem newOutputItem = new OutputItem(inputItemId, _quantities[quantId],
                                                                _elementSets[elementSetId], this);
                newOutputItem.StoreValuesInExchangeItem = true;
                EngineOutputItems.Add(newOutputItem);
            }
            else
            {
                throw new Exception("Unknown inOrOutOption: " + inOrOut);
            }
        }
        public override void Initialize()
        {
            var properties = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);

            foreach (IArgument argument in Arguments)
            {
                properties.Add(argument.Id, argument.Value);
            }
            string simFileName = "SimpleRiver.sim";
            object value;

            if (properties.TryGetValue("SimFileName", out value) && value != null && value.ToString().Length > 1)
            {
                simFileName = value.ToString();
            }
            // -- Create and initialize the engine --
            if (properties.TryGetValue("FilePath", out value) && value != null && value.ToString().Length > 1)
            {
                _simpleRiverEngine.Initialize(value.ToString(), simFileName);
            }
            else
            {
                string currentDir = System.IO.Directory.GetCurrentDirectory();
                _simpleRiverEngine.Initialize(currentDir, simFileName);
                //When running from the GUI, the assembly is started with the current dir
                //to the location of the OMI files. It is assumed that the data files are
                //located in the same directory.
            }

            if (properties.TryGetValue("TimeStepLength", out value) && value != null && ((double)value) > 0.0)
            {
                _simpleRiverEngine.SetTimeStepLength(Convert.ToDouble(value));
            }

            if (properties.TryGetValue("ModelId", out value) && value != null)
            {
                // Note: This does strictly not set the id to the fortran engine (no setter available)
                Id = value.ToString();
            }
            else
            {
                Id = _simpleRiverEngine.GetModelID();
            }

            Description = _simpleRiverEngine.GetModelDescription();

            // -- Time horizon --
            char[]   delimiter   = new char[] { '-', ' ', ':' };
            string[] strings     = _simpleRiverEngine.GetSimulationStartDate().Split(delimiter);
            int      StartYear   = Convert.ToInt32(strings[0]);
            int      StartMonth  = Convert.ToInt32(strings[1]);
            int      StartDay    = Convert.ToInt32(strings[2]);
            int      StartHour   = Convert.ToInt32(strings[3]);
            int      StartMinute = Convert.ToInt32(strings[4]);
            int      StartSecond = Convert.ToInt32(strings[5]);
            DateTime startDate   = new DateTime(StartYear, StartMonth, StartDay, StartHour, StartMinute, StartSecond);

            _simulationStartTime = new Time(startDate).StampAsModifiedJulianDay;


            // -- Build exchange items ---
            Dimension flowDimension = new Dimension();

            flowDimension.SetPower(DimensionBase.Length, 3);
            flowDimension.SetPower(DimensionBase.Time, -1);

            Unit flowUnit = new Unit("m3/sec", 1, 0, "m3/sec");

            flowUnit.Dimension = flowDimension;

            Quantity flowQuantity   = new Quantity(flowUnit, "Flow description", "Flow");
            Quantity inFlowQuantity = new Quantity(flowUnit, "Inflow description", "InFlow");

            // ADH: Might not be unreasonable to set double as default in backbone constructor
            flowQuantity.ValueType   = typeof(double);
            inFlowQuantity.ValueType = typeof(double);

            int numberOfNodes = _simpleRiverEngine.GetNumberOfNodes();

            TimeSet timeset = new TimeSet();

            timeset.TimeHorizon = GetTimeHorizon();

            TimeSet extentTimeSet = new TimeSet();

            extentTimeSet.TimeHorizon = GetTimeHorizon();
            extentTimeSet.Times.Add(GetTimeHorizon());
            _timeExtent = extentTimeSet;

            int nCount = 0;

            for (int i = 0; i < numberOfNodes - 1; i++)
            {
                ElementSet branch = new ElementSet("description", "Branch:" + i, ElementType.PolyLine, "");
                branch.AddElement(new Element("Branch:" + i.ToString()));
                branch.Elements[0].AddVertex(new Coordinate(_simpleRiverEngine.GetXCoordinate(i), _simpleRiverEngine.GetYCoordinate(i), 0));
                branch.Elements[0].AddVertex(new Coordinate(_simpleRiverEngine.GetXCoordinate(i + 1), _simpleRiverEngine.GetYCoordinate(i + 1), 0));

                EngineEOutputItem flowFromBrach = new EngineEOutputItem("Branch:" + i + ":Flow", flowQuantity, branch, this);

                int branchIndex = i;
                EngineDInputItem inflowToBranch = new EngineDInputItem("Branch:" + i + ":InFlow", inFlowQuantity, branch, this);
                inflowToBranch.ValueSetter = delegate(ITimeSpaceValueSet values)
                {
                    _simpleRiverEngine.AddInflow(branchIndex, (double)values.GetValue(0, 0));
                };

                flowFromBrach.TimeSet = timeset;

                EngineOutputItems.Add(flowFromBrach);
                EngineInputItems.Add(inflowToBranch);
            }

            for (int i = 0; i < numberOfNodes; i++)
            {
                ElementSet node = new ElementSet("description", "Node:" + i.ToString(), ElementType.IdBased, "");
                node.AddElement(new Element("Node:" + i.ToString()));

                int nodeIndex = i;
                EngineDInputItem inflowToNode = new EngineDInputItem(node.Caption + ":InFlow", inFlowQuantity, node, this);
                inflowToNode.ValueSetter = delegate(ITimeSpaceValueSet values)
                {
                    _simpleRiverEngine.AddInflow(nodeIndex, (double)values.GetValue(0, 0));
                };
                Inputs.Add(inflowToNode);
            }

            ElementSet branches = new ElementSet("description", "AllBranches", ElementType.PolyLine, "");

            for (int i = 0; i < numberOfNodes - 1; i++)
            {
                Element branch = new Element("Branch: " + i.ToString());
                branch.AddVertex(new Coordinate(_simpleRiverEngine.GetXCoordinate(i), _simpleRiverEngine.GetYCoordinate(i), 0));
                branch.AddVertex(new Coordinate(_simpleRiverEngine.GetXCoordinate(i + 1), _simpleRiverEngine.GetYCoordinate(i + 1), 0));
                branches.AddElement(branch);
            }

            EngineEInputItem inFlowToBraches = new EngineEInputItem(branches.Caption + ":inFlow", inFlowQuantity, branches, this);

            Inputs.Add(inFlowToBraches);

            Status = LinkableComponentStatus.Initialized;
        }
Example #3
0
        public override void Initialize()
        {
            Status = LinkableComponentStatus.Initializing;

            Hashtable hashtable = new Hashtable();

            for (int i = 0; i < Arguments.Count; i++)
            {
                hashtable.Add(Arguments[i].Caption, Arguments[i].Value);
            }

            if (_engineApiAccess == null)
            {
                throw new Exception("Failed to assign the engine");
            }

            _engineApiAccess.Initialize(hashtable);

            //foreach (InputItem inputItem in inputItems)
            //{
            //    TimeSet timeset = new TimeSet();
            //    timeset.Times.Add(TimeHelper.ConvertTime(_engineApiAccess.GetCurrentTime()));
            //    inputItem.TimeSet = timeset;
            //    // TODO inputItem.TimeSet = TimeSet for input item;
            //}
            //foreach (OutputItem outputItem in outputItems)
            //{
            //    TimeSet timeset = new TimeSet();
            //    timeset.Times.Add(TimeHelper.ConvertTime(_engineApiAccess.GetCurrentTime()));
            //    outputItem.TimeSet = timeset;
            //}

            Id          = _engineApiAccess.GetModelID();
            Description = _engineApiAccess.GetModelDescription();

            for (int i = 0; i < _engineApiAccess.GetOutputExchangeItemCount(); i++)
            {
                OutputExchangeItem output       = _engineApiAccess.GetOutputExchangeItem(i);
                IQuantity          quantity     = output.Quantity;
                IElementSet        elementSet   = output.ElementSet();
                String             outputItemId = string.IsNullOrEmpty(output.Id) ? elementSet.Caption + ":" + quantity.Caption : output.Id;
                EngineOutputItem   outputItem   = new EngineEOutputItem(outputItemId, quantity, elementSet, this);
                outputItem.TimeSet.SetSingleTime(TimeHelper.ConvertTime(_engineApiAccess.GetTimeHorizon().Start));
                outputItem.TimeSet.SetTimeHorizon(TimeHelper.ConvertTime(_engineApiAccess.GetTimeHorizon()));
                EngineOutputItems.Add(outputItem);
            }

            for (int i = 0; i < _engineApiAccess.GetInputExchangeItemCount(); i++)
            {
                InputExchangeItem input       = _engineApiAccess.GetInputExchangeItem(i);
                IQuantity         quantity    = input.Quantity;
                IElementSet       elementSet  = input.ElementSet();
                String            inputItemId = string.IsNullOrEmpty(input.Id) ? elementSet.Caption + ":" + quantity.Caption : input.Id;
                EngineInputItem   inputItem   = new EngineEInputItem(inputItemId, quantity, elementSet, this);
                inputItem.TimeSet.SetSingleTime(TimeHelper.ConvertTime(_engineApiAccess.GetTimeHorizon().Start));
                inputItem.TimeSet.SetTimeHorizon(TimeHelper.ConvertTime(_engineApiAccess.GetTimeHorizon()));
                EngineInputItems.Add(inputItem);
            }


            Status = LinkableComponentStatus.Initialized;
            _initializeWasInvoked = true;
        }
Example #4
0
        public override void Initialize()
        {
            Status = LinkableComponentStatus.Initializing;

            // Handle arguments
            IDictionary <string, IArgument> argDict = Arguments.Dictionary();

            Id           = argDict.GetValue <string>("ModelId");
            this.Caption = "RiverModel Default Model";

            _flowItemsAsSpan         = argDict.GetValue <bool>("FlowItemsAsSpan");
            _storeValuesInItem       = argDict.GetValue <bool>("StoreValuesInExchangeitems");
            _timeStepLengthInSeconds = argDict.GetValue <double>("TimestepLength");
            _timeStepLengthInDays    = _timeStepLengthInSeconds / (24.0 * 3600.0);

            double xyscale = argDict.GetValue <double>("xyscale");
            double xOffset = argDict.GetValue <double>("xoffset");
            double yOffset = argDict.GetValue <double>("yoffset");

            for (int i = 0; i < _numberOfNodes; i++)
            {
                _xCoordinate[i] = xyscale * _xCoordinate[i] + xOffset;
                _yCoordinate[i] = xyscale * _yCoordinate[i] + yOffset;
            }

            // -- create a flow quantity --
            Dimension flowDimension = new Dimension();

            flowDimension.SetPower(DimensionBase.Length, 3);
            flowDimension.SetPower(DimensionBase.Time, -1);

            Unit literPrSecUnit = new Unit("LiterPrSecond", 0.001, 0, "Liters pr Second");

            Quantity flowQuantity    = new Quantity(literPrSecUnit, "Flow", "Flow");
            Quantity leakageQuantity = new Quantity(literPrSecUnit, "Leakage", "Leakage");

            // -- create a ground water level quantity --
            Dimension levelDimension = new Dimension();

            levelDimension.SetPower(DimensionBase.Length, 1);

            Unit levelUnit = new Unit("GroundWaterLevel", 1, 0, "Ground water level");

            levelUnit.Dimension = levelDimension;

            Quantity levelQuantity = new Quantity(levelUnit, "Ground water level", "Ground Water level");

            // -- Time settings for input and output exchange items --
            ITime timeHorizon = new Time(StartTime, EndTime);

            // -- create and populate elementset to represent all branches, links betwen nodes in the river network --
            LineString fullRiverLineString =
                new LineString
            {
                Coordinates = GeometryFactory.CreateCoordinateList(_xCoordinate, _yCoordinate),
                Caption     = "WholeRiver",
                Description = "WholeRiver",
                IsClosed    = false,
                IsNodeBased = false,
            };
            IElementSet fullRiverElementSet = new LineStringWrapper(fullRiverLineString);

            // --- populate input exchange items for flow to individual nodes, id-based ---
            for (int i = 0; i < _numberOfNodes; i++)
            {
                string     id         = "Node:" + i;
                ElementSet elementSet = new ElementSet(id, id, ElementType.IdBased);
                elementSet.AddElement(new Element(id));

                EngineInputItem inputExchangeItem = CreateInputInflowToOneNode(i, id, flowQuantity, elementSet);
                inputExchangeItem.StoreValuesInExchangeItem = true; // Item is adding up, therefor store in item
                inputExchangeItem.TimeSet.SetTimeHorizon(timeHorizon);
                EngineInputItems.Add(inputExchangeItem);
            }

            // --- Populate input exchange item for flow into the whole river ---
            EngineInputItem wholeRiverFlowInputItem = CreateInputInflowToRiver(flowQuantity, fullRiverElementSet);

            wholeRiverFlowInputItem.TimeSet.SetTimeHorizon(timeHorizon);
            EngineInputItems.Add(wholeRiverFlowInputItem);

            // --- Populate input exchange item for ground water level of the whole river ---
            EngineDInputItem gwLevelInputItem = CreateInputGwLevel(levelQuantity, fullRiverElementSet);

            gwLevelInputItem.TimeSet.SetTimeHorizon(timeHorizon);
            EngineInputItems.Add(gwLevelInputItem);

            // --- Populate output exchange items for flow in river branches, id based ---
            for (int i = 0; i < _numberOfNodes - 1; i++)
            {
                string     id         = "Branch:" + i;
                ElementSet elementSet = new ElementSet(id, id, ElementType.IdBased);
                elementSet.AddElement(new Element(id));

                EngineOutputItem outputExchangeItem = CreateOutputFlowInBranch(i, id, flowQuantity, elementSet);
                EngineOutputItems.Add(outputExchangeItem);
            }

            // --- populate output exchange items for leakage for individual branches --
            for (int i = 0; i < _numberOfNodes - 1; i++)
            {
                string     id         = "Branch:" + i;
                ElementSet elementSet = new ElementSet(id, id, ElementType.IdBased);
                elementSet.AddElement(new Element(id));

                EngineOutputItem outputExchangeItem = CreateOutputLeakageInBranch(i, id, leakageQuantity, elementSet);
                EngineOutputItems.Add(outputExchangeItem);
            }

            // --- Populate output exchange item for leakage from the whole georeferenced river ---
            EngineOutputItem wholeRiverOutputExchangeItem = CreateOuputLeakageInRiver(leakageQuantity, fullRiverElementSet);

            EngineOutputItems.Add(wholeRiverOutputExchangeItem);

            // --- Populate output exchange item for flow from the whole georeferenced river ---
            EngineOutputItem wholeRiverFlowOutputExchangeItem = CreateOutputFlowInRiver(flowQuantity, fullRiverElementSet);

            EngineOutputItems.Add(wholeRiverFlowOutputExchangeItem);

            // --- populate with initial state variables ---
            for (int i = 0; i < _numberOfNodes - 1; i++)
            {
                _flow[i] = 7;
            }

            foreach (EngineInputItem engineInputItem in EngineInputItems)
            {
                // TODO: Overwrites existing timeset, which has already had the time horizon set?
                engineInputItem.TimeSet = new TimeSet()
                {
                    HasDurations = _flowItemsAsSpan
                };
            }
            foreach (EngineOutputItem engineOutputItem in EngineOutputItems)
            {
                // TODO: Overwrites existing timeset, which has already had the time horizon set?
                engineOutputItem.TimeSet = new TimeSet()
                {
                    HasDurations = _flowItemsAsSpan
                };
            }

            Status = LinkableComponentStatus.Initialized;
        }
Example #5
0
        public override void Initialize()
        {
            Status = LinkableComponentStatus.Initializing;

            ReadArguments();

            // Initialize storage vector
            _storage = new double[NumberOfElements];

            for (int i = 0; i < NumberOfElements; i++)
            {
                _storage[i] = 0;
            }

            // -- Populate Exchange Items ---

            // Element set for a grid based (polygons) item
            Spatial2DRegularGrid regularGrid = new Spatial2DRegularGrid()
            {
                Description = "RegularGrid",
                Caption     = "RegularGrid",
                Dx          = _dx,
                Dy          = _dy,
                X0          = _x0,
                Y0          = _y0,
                XCount      = _xCount,
                YCount      = _yCount,
                Orientation = _orientation,
                IsNodeBased = false,
            };
            Spatial2DGridWrapper regularElmtSet = new Spatial2DGridWrapper(regularGrid);

            // Element set for a Polygon based item, of the lower left cell in the grid
            Element element0 = new Element("element:0");

            element0.AddVertex(new Coordinate(_x0, _y0, 0));
            element0.AddVertex(new Coordinate(_x0 + _dx, _y0, 0));
            element0.AddVertex(new Coordinate(_x0 + _dx, _y0 + _dy, 0));
            element0.AddVertex(new Coordinate(_x0, _y0 + _dy, 0));

            // Element set for an ID based item, of the lower left cell in the grid
            ElementSet idSet =
                new ElementSet("FirstElement", "FirstElement", ElementType.IdBased);

            idSet.AddElement(element0); // is an IdBased set required to have elements?

            // Dimensions
            Dimension dimVolume = new Dimension();

            dimVolume.SetPower(DimensionBase.Length, 3);

            Dimension dimLength = new Dimension();

            dimLength.SetPower(DimensionBase.Length, 1);

            Dimension dimDischarge = new Dimension();

            dimDischarge.SetPower(DimensionBase.Length, 3);
            dimDischarge.SetPower(DimensionBase.Time, -1);

            // Units
            Unit unitLiterStorage = new Unit("Storage", 0.001, 0.0, "Storage");

            unitLiterStorage.Dimension = dimVolume;

            Unit unitGwLevel = new Unit("gw level", 1.0, 0.0, "Ground water level");

            unitGwLevel.Dimension = dimLength;

            Unit unitDischarge = new Unit("Discharge", 0.001, 0, "Discharge into ground water model, [L/s]");

            unitDischarge.Dimension = dimDischarge;

            // Quantities
            Quantity quantityStorage = new Quantity(unitLiterStorage, "Storage", "Storage");

            Quantity quantityGwLevel = new Quantity(unitGwLevel, "Ground water level", "Ground water level");

            Quantity quantityInflow = new Quantity(unitDischarge, "Inflow into ground water model", "Inflow");


            // Storage input on the grid
            _storageInput             = new EngineEInputItem("Grid.Storage", quantityStorage, regularElmtSet, this);
            _firstElementStorageInput = new EngineEInputItem("FirstElement.Storage", quantityStorage, idSet, this);

            // Storage output on the grid
            _storageOutput = new EngineEOutputItem("Grid.Storage", quantityStorage, regularElmtSet, this);
            _storageOutput.TimeSet.SetSingleTime(StartTime);
            _storageOutput.TimeSet.SetTimeHorizon(new Time(StartTime, EndTime));

            // Storage output in the first element of the grid
            _firstElementStorageOutput = new EngineEOutputItem("FirstElement.Storage", quantityStorage, idSet, this);
            _firstElementStorageOutput.TimeSet.SetSingleTime(StartTime);
            _firstElementStorageOutput.TimeSet.SetTimeHorizon(new Time(StartTime, EndTime));


            // Ground water level output. Calculated as (_gwBaseLevel + 0.1*storage height), assuming that the
            // water can populate 10% of the ground volume.
            EngineDOutputItem gwLevelOutput = new EngineDOutputItem("Grid.gwLevel", quantityGwLevel, regularElmtSet, this);

            gwLevelOutput.StoreValuesInExchangeItem = false;
            gwLevelOutput.ValueGetter = delegate()
            {
                IList <double> res = new List <double>(NumberOfElements);
                for (int i = 0; i < NumberOfElements; i++)
                {
                    // Convert storage from liters to m3 and find the height.
                    double storageHeight = 0.001 * _storage[i] / (_dx * _dy);
                    res.Add(_gwBaseLevel + 10 * storageHeight);
                }
                return(new ValueSet(new List <IList> {
                    (IList)res
                }));
            };

            // Ground water inflow in the grid
            EngineDInputItem gwInflow = new EngineDInputItem("Grid.Inflow", quantityInflow, regularElmtSet, this);

            gwInflow.ValueSetter = delegate(ITimeSpaceValueSet values)
            {
                IList elmtValues = values.GetElementValuesForTime(0);
                for (int i = 0; i < NumberOfElements; i++)
                {
                    // Values arrive in [L/s], storage is in liters.
                    _storage[i] += (double)elmtValues[i] * _timeStepLengthInSeconds;
                    if (_storage[i] < 0)                // inflow can be negative, but storage can not be zero. Mass error here :-(
                    {
                        _storage[i] = 0;
                    }
                }
            };

            EngineOutputItems.Add(_storageOutput);
            EngineOutputItems.Add(_firstElementStorageOutput);
            EngineOutputItems.Add(gwLevelOutput);

            EngineInputItems.Add(_storageInput);
            EngineInputItems.Add(_firstElementStorageInput);
            if (_useMultiInput)
            {
                EngineInputItems.Add(new EngineMultiInputItemWrapper(gwInflow, this));
            }
            else
            {
                EngineInputItems.Add(gwInflow);
            }

            Status = LinkableComponentStatus.Initialized;
        }