protected override EngineOutputItem CreateOutputFlowInRiver(Quantity flowQuantity, IElementSet fullRiverElementSet) { EngineDOutputItem wholeRiverFlowOutputExchangeItem = new EngineDOutputItem("WholeRiver:Flow", flowQuantity, fullRiverElementSet, this); wholeRiverFlowOutputExchangeItem.ValueGetter = GetFlowValues; return(wholeRiverFlowOutputExchangeItem); }
protected override EngineOutputItem CreateOutputFlowInBranch(int branchIndex, string id, Quantity flowQuantity, ElementSet elementSet) { EngineDOutputItem outputExchangeItem = new EngineDOutputItem(id + ":Flow", flowQuantity, elementSet, this); outputExchangeItem.ValueGetter = delegate() { IList res = new List <double>(1) { _flow[branchIndex] }; return(new ValueSet(new List <IList> { res })); }; return(outputExchangeItem); }
protected override EngineOutputItem CreateOutputLeakageInBranch(int i, string id, Quantity leakageQuantity, ElementSet elementSet) { EngineDOutputItem outputExchangeItem = new EngineDOutputItem(id + ":Leakage", leakageQuantity, elementSet, this); int branchIndex = i; outputExchangeItem.ValueGetter = delegate() { IList res = new List <double>(1) { _leakage[branchIndex] }; return(new ValueSet(new List <IList> { res })); }; return(outputExchangeItem); }
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; }