Hello There,
I am using WaterObjects.NET to automate Hammer for sensitivity and calibration purpose. I can open the project, get/set pipe parameters, but get stuck in running Hammer engine. My questions are:1 Is it possible to run epanet (as show in RunEpaNet(...)) with only Hammer license? We only have Hammer license.2 I have to call the project.Save(property); to save my edits, eg pipe diameter and wave speed, is my way of generating ProjectProperty correct?3 When i come toline hammerEngine.Run(domainDataSet.ScenarioManager.Elements()); I always get error NullReference. After I call SetUnitReference(project.NumericPresentationManager), the NullReference error was gone, but get another error msg (please note I can see the scenarios running window): "The process cannot access the file 'C:\\Users\\hshen\\AppData\\Local\\Temp\\Bentley\\HAMMER\\test PRV.wtg.6.$$$_1_1.hof' because it is being used by another process."
Thanks for the help,
Hailiang
Here are my codes:
private const string VERSION = "08.11.05.61";
public Form1() { InitializeComponent(); }
private void btnRun_Click(object sender, EventArgs e) { //RunEpaNet();
#region Open a wtg project
IProjectApplicationModel aprojectApplicationModel = (IProjectApplicationModel)new Haestad.Toronto.Application.TorontoApplicationModel(LicensePlatformType.Standalone, VERSION, new string[] { });
Haestad.Toronto.Application.TorontoParentFormModel parentFormModel = new Haestad.Toronto.Application.TorontoParentFormModel(aprojectApplicationModel); Haestad.Toronto.Application.TorontoParentFormUIModel parentFormUIModel = new Haestad.Toronto.Application.TorontoParentFormUIModel(parentFormModel); parentFormUIModel.InitializeOnStartUp();
// opem hammer project bool sucess = parentFormUIModel.OpenFileWithSpecifiedExtension(txtInput.Text, false); if (sucess) { Haestad.Toronto.Application.TorontoProject project = parentFormModel.CurrentProject as Haestad.Toronto.Application.TorontoProject; Haestad.HAMMER.TransientResultsViewer.Domain.TransientResultsProjectContext projectContext = new Haestad.HAMMER.TransientResultsViewer.Domain.TransientResultsProjectContext( project.ProjectManager, project.TransientResultsViewerProfileElementManager, project.TransientResultsViewerTimeHistoryElementManager, project.TransientResultsViewerNodeHistoryElementManager);
Haestad.Framework.Application.ProjectProperties property = Haestad.Framework.Application.ProjectProperties.DefaultNominalProjectPath(txtInput.Text); Haestad.Domain.ModelingObjects.Water.IdahoDomainDataSet domainDataSet = project.IdahoDomainDataSet; this.RunScenarios(project);
project.Save(property); }
#endregion }
private void RunEpaNet(string inp = @"C:\Program Files (x86)\EPANET2\Examples\Net3.inp") { // using Haestad.Calculations.Pressure.NumericalEngine.EngineAdapter will not work for the license limit. Haestad.Calculations.Pressure.NumericalEngine.EngineAdapter adapter = new Haestad.Calculations.Pressure.NumericalEngine.EngineAdapter(); adapter.SetLicensingInfo(this.RetrieveLicense()); adapter.Open(inp, "", ""); adapter.OpenHydraulicEngine(); adapter.InitializeHydraulicEngine(true); }
private void RunScenarios(Haestad.Toronto.Application.TorontoProject project) { try { // run all scenarios at first Haestad.Domain.ModelingObjects.Water.IdahoDomainDataSet domainDataSet = project.IdahoDomainDataSet; Haestad.Calculations.Hammer.Domain.HammerNumericalEngine hammerEngine = (Haestad.Calculations.Hammer.Domain.HammerNumericalEngine)domainDataSet.NumericalEngine(Haestad.Domain.StandardCalculationOptionFieldName.HammerNumericalEngine);
//Haestad.Calculations.Hammer.Domain.HammerNumericalEngine hammerEngine = new Haestad.Calculations.Hammer.Domain.HammerNumericalEngine(domainDataSet, Haestad.Domain.StandardCalculationOptionFieldName.HammerNumericalEngine);
hammerEngine.SetUnitReference(project.NumericPresentationManager); hammerEngine.SetLicensingInfo(this.RetrieveLicense()); hammerEngine.ComputeInitialConditionsSetting = Haestad.Calculations.Hammer.Domain.ComputeInitialConditionSetting.AlwaysCompute;
Haestad.Domain.ModelingElementCollection modelingElementCollection = new Haestad.Domain.ModelingElementCollection(); modelingElementCollection.Add(domainDataSet.ScenarioManager.Element(1)); if (!hammerEngine.IsRunning(1)) { hammerEngine.Run(modelingElementCollection); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
private Haestad.Support.Support.HmIDCollection GetScenarioIds(Haestad.Domain.ModelingObjects.Water.IdahoDomainDataSet domainDataSet) { return domainDataSet.ScenarioManager.ElementIDs(); }
private Haestad.LicensingFacade.License RetrieveLicense() { // is relevant to an engine, not specific to a project. A project may require multiple licenses, eg hammer requires both epanet and hammer ProductRelease release = new ProductRelease(ProductId.Bentley_HAMMER, VERSION); Haestad.LicensingFacade.License license = Haestad.LicensingFacade.License.Default(release); license.StartDesktop(true); return license; }
Hello Shenh,
For your first question, as far as I know, there should not be an issue running the steady state/eps solver with only a HAMMER license. This is done in HAMMER itself to establish initial conditions for a transient analysis. For the other problem with running the solver, check out the below forum threads, which are also related to running the HAMMER solver with Waterobjects. Let us know if this doesn't help and we'll get some input from the development team.
https://communities.bentley.com/products/hydraulics___hydrology/f/5925/t/100796
https://communities.bentley.com/products/hydraulics___hydrology/f/5925/t/100798
Regards,
Jesse DringoliTechnical Support Manager, OpenFlowsBentley Communities Site AdministratorBentley Systems, Inc.
Hi Shenh, I'm surprised it is not working for you. I apologize. So, let's see if we can diagnose what is going on. For the OwnerWindow to be valid, implement IUserInterface defined in Haestad.Framework.Application on your main form. For the Open(IApplicationContext) and ModelessFormClosing() methods just leave them as no-ops. For the OwnerWindow property, return "this" (no quotes) which would be your Form. The interface must be implemented on your Form for this to work. The TorontoApplicationModel has a method called SetCOMUserInterface. Once your form implements IUserInterface you can pass it into this method. It will set the proper internals so down the line UserInterface on the ApplicationModel is no longer null. Once you do the above you should be able to call SelectAll() and then call BatchRun(). The license is set automatically for you since you are using the Application Framework API. When you compute, the license is retrieved from the LicenseFeatureSet property of the ApplicationModel. The license will also be released upon proper closure of the application (one of the reasons why calling CloseParentFormUIModel() is so important when your main form closes and the application ends). The license is appropriately applied to both the water and HAMMER engines as needed using the SetLicensingInfo method. If you do not want to run all scenarios (that is what I interpreted in your original posting) then there is a simpler way to compute the HAMMER engine. //Compute the initial conditions with the Water engine. aparentFormUIModel.ExecuteCommand(CommandType.CurrentScenario, scenarioId); //Compute the transient analysis with the HAMMER engine aparentFormUIModel.ExecuteCommand(CommandType.ComputeHammer, scenarioId); The scenarioId value does not have to be the Active Scenario. It can be any valid scenario ID in the model. The code will blow up if this is not a valid scenario id. I hope that helps. Kris
Answer Verified By: shenh