public void OnSoluteChanged(SoluteChangedType SoluteChanges) { if (SoluteChanges.SoluteName == SoluteType.Name) { // The amount of this solute has changed, check values and make changes changeSoluteAmount(SoluteChanges); } }
public override void MakeSoluteDiffusionEffective() { SoluteChangedType SoluteChanges = new SoluteChangedType(); SoluteChanges.Sender = "SoluteDiffusion"; SoluteChanges.SoluteName = Name; SoluteChanges.SoluteUnits = "kg/ha"; SoluteChanges.DeltaSolute = deltaSoluteDiffusion; SoluteChanged.Invoke(SoluteChanges); }
/// <summary> /// Updates the the values for the amount of solute, following changes /// </summary> /// <remarks> /// The amount is stored in mol/kg, so the changes should be convereted approapriately /// </remarks> /// <param name="SoluteChanges">Data about solute changes (name and amount)</param> private void changeSoluteAmount(SoluteChangedType SoluteChanges) { double convFactor = 0.0; for (int Layer = 0; Layer < dlayer.Length; Layer++) { if (SoluteChanges.DeltaSolute[Layer] != 0.0) { // The amount has changed, check units and apply delta double DeltaAmount = 0.0; switch (SoluteChanges.SoluteUnits.ToLower()) { case "kg/ha": convFactor = 10 * MolecularWeight * dlayer[Layer] * bd[Layer]; DeltaAmount = SoluteChanges.DeltaSolute[Layer] / convFactor; // convert to mol/kg break; case "ppm": case "mg/kg": convFactor = 1000 * MolecularWeight; DeltaAmount = SoluteChanges.DeltaSolute[Layer] / convFactor; // convert to mol/kg break; case "mol/kg": DeltaAmount = SoluteChanges.DeltaSolute[Layer]; // already correct break; default: throw new Exception("The units for " + SoluteType.Name + " are not recognised, values passed by " + SoluteChanges.Sender); } double Result = Amount[Layer] + DeltaAmount; // Check bounds if (Result < MinimumConcentration - ToleranceValue) { throw new Exception("Attempt to set the value of " + SoluteType.Name + " to a value below its lower bound"); } else if (Result > MaximumConcentration + ToleranceValue) { throw new Exception("Attempt to set the value of " + SoluteType.Name + " to a value above its upper bound"); } else { Amount[Layer] = Math.Max(MinimumConcentration, Math.Min(MaximumConcentration, Result)); } } } // Update values in SoluteType SoluteType.NewSoluteAmount(Amount_kgha(), Amount_mgkg()); }
/// <summary> /// Make the changes from solute degradation effective . Uses the SoluteChanged event /// </summary> public override void EffectivateSoluteDegradation() { SoluteChangedType SoluteChanges = new SoluteChangedType(); // First reduce the amount of this solute SoluteChanges.Sender = "SoluteDegradation"; SoluteChanges.SoluteName = Name; SoluteChanges.SoluteUnits = "kg/ha"; SoluteChanges.DeltaSolute = deltaSoluteTransformed; SoluteChanged.Invoke(SoluteChanges); // Now increase the degradation product (assumed also solute) SoluteChanges.Sender = "SoluteDegradation"; SoluteChanges.SoluteName = ProductName; SoluteChanges.SoluteUnits = "kg/ha"; SoluteChanges.DeltaSolute = Array.ConvertAll(deltaSoluteTransformed, i => - i); SoluteChanged.Invoke(SoluteChanges); }
/// <summary> /// Make the changes from solute degradation effective . Uses the SoluteChanged event /// </summary> public override void MakeSoluteDegradationEffective() { // First reduce the amount of this solute SoluteChangedType SoluteChanges = new SoluteChangedType(); SoluteChanges.Sender = "SoluteDegradation"; SoluteChanges.SoluteName = Name; SoluteChanges.SoluteUnits = "kg/ha"; SoluteChanges.DeltaSolute = deltaSoluteTransformed; SoluteChanged.Invoke(SoluteChanges); // Now increase the degradation product (assumed also solute) NitrogenChangedType NitrogenChanges = new NitrogenChangedType(); NitrogenChanges.Sender = "SoluteDegradation"; NitrogenChanges.SenderType = "Solute"; NitrogenChanges.DeltaUrea = Array.ConvertAll(deltaSoluteTransformed, i => - i); NitrogenChanged.Invoke(NitrogenChanges); }