From de9304cacca36cc244dda0c0404801b36eee55dc Mon Sep 17 00:00:00 2001 From: jkauttio Date: Tue, 21 Apr 2015 09:45:09 +0000 Subject: [PATCH] Filter simulation results based on the given simulation parameters. Also fix a possible bug in the way the output interval was applied with openmodelica and sensitivity analysis experiments. fixes #5785 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@31191 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../org/simantics/modelica/data/DataSet.java | 41 ++++++++++++++++++- .../sysdyn/manager/MemoryResult.java | 21 ++++++++++ .../sysdyn/manager/OldSysdynExperiment.java | 16 +++++--- .../SysdynSensitivityAnalysisExperiment.java | 16 +++++--- 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java b/org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java index c1c4bae9..f373b988 100644 --- a/org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java +++ b/org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java @@ -24,5 +24,44 @@ public class DataSet { this.name = name; this.times = times; this.values = values; - } + } + + /** + * Normalize simulation results according to the given parameters by + * removing extra simulation steps that are not located at the expected + * intervals. This is mostly useful when Open Modelica decides to perform + * extra simulation steps that cause misalignments when simulation results + * from several runs with different parameters are combined in sensitivity + * analysis experiments. + * + * @param startTime + * @param stopTime + * @param timeStep + */ + public void filter(double startTime, double stopTime, double timeStep) { + // TODO: this makes implicit assumptions about the values, probably not kosher + int size = (int)Math.round((stopTime - startTime) / timeStep) + 1; + if (times.length < size) { + // if the ogirinal data has less time steps than requested, there is no need + // to filter anything. generally this happens when the value of the variable + // does not change during the simulation, in which case Open Modelica + // simply stores the value once. + return; + } + double[] newTimes = new double[size]; + double[] newValues = new double[size]; + + // simply skip all simulation steps that are not at the expected intervals + int old = 0; + for (int i = 0; i < size; i++) { + newTimes[i] = startTime + i * timeStep; + while (times[old] < newTimes[i] && old != times.length - 1) { + old++; + } + newValues[i] = values[old]; + } + + times = newTimes; + values = newValues; + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/MemoryResult.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/MemoryResult.java index f6ef5bb5..d3ffbd79 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/MemoryResult.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/MemoryResult.java @@ -44,6 +44,11 @@ public class MemoryResult extends SysdynResult { private File resultFile; private Integer resultIndex = null; private SimulationResult simulationResult; + + private boolean filter = false; + private double startTime; + private double stopTime; + private double timeStep; /** @@ -76,6 +81,11 @@ public class MemoryResult extends SysdynResult { ds = simulationResult.readVariable(variable, resultFile); if(ds != null) { + if (filter) { + // filter the data set, not completely sure if this is the correct + // place to do this but seems fine enough + ds.filter(startTime, stopTime, timeStep); + } SysdynDataSet sds = new SysdynDataSet(ds.name, getResultName(), ds.times, ds.values, resultIndex); results.put(variable, sds); return sds; @@ -92,6 +102,17 @@ public class MemoryResult extends SysdynResult { return null; } + + public void setFilter(double start, double stop, double step) { + this.filter = true; + this.startTime = start; + this.stopTime = stop; + this.timeStep = step; + } + + public void unsetFilter() { + this.filter = false; + } public void setResultFile(File resFile) { this.resultFile = resFile; diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java index f1701ee9..3fbd472c 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java @@ -362,20 +362,23 @@ public class OldSysdynExperiment extends SysdynExperiment { else result = new MatSimulationResult(); // The latest format + String startTime = experimentParameters.get(ModelicaKeys.START_VALUE); + String stopTime = experimentParameters.get(ModelicaKeys.STOP_VALUE); + String stepTime = experimentParameters.get(ModelicaKeys.STEP_VALUE); + + Double start = Double.parseDouble(startTime); + Double stop = Double.parseDouble(stopTime); + Double step = Double.parseDouble(stepTime); + // The interval of results saved. Every result? Every other result? etc... int outIntervalInt = 1; String outputInterval = experimentParameters.get(ModelicaKeys.OUTPUT_INTERVAL); if(outputInterval != null) { - String stepTime = experimentParameters.get(ModelicaKeys.STEP_VALUE); - String stopTime = experimentParameters.get(ModelicaKeys.STOP_VALUE); - - Double step = Double.parseDouble(stepTime); - Double stop = Double.parseDouble(stopTime); Double outInterval = Double.parseDouble(outputInterval); outIntervalInt = (int)getInterval(outInterval, step); // Actually you might be able to use an outInterval one or two longer. - int maxIntervalInt = (int)Math.round(stop / step); + int maxIntervalInt = (int)Math.round((stop - start) / step); if (outIntervalInt > maxIntervalInt) outIntervalInt = maxIntervalInt; } @@ -386,6 +389,7 @@ public class OldSysdynExperiment extends SysdynExperiment { result.filter(); ((MemoryResult)getCurrentResult()).setResult(result); ((MemoryResult)getCurrentResult()).setResultFile(simulationLocation.resultFile); + ((MemoryResult)getCurrentResult()).setFilter(start, stop, step); progressMonitor.worked(1); resultsChanged(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java index 063c3867..bb5f2b11 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java @@ -236,21 +236,24 @@ public class SysdynSensitivityAnalysisExperiment extends OldSysdynExperiment { result = new SimulationResult(); else result = new MatSimulationResult(); // The latest format + + String startTime = experimentParameters.get(ModelicaKeys.START_VALUE); + String stopTime = experimentParameters.get(ModelicaKeys.STOP_VALUE); + String stepTime = experimentParameters.get(ModelicaKeys.STEP_VALUE); + + Double start = Double.parseDouble(startTime); + Double stop = Double.parseDouble(stopTime); + Double step = Double.parseDouble(stepTime); // The interval of results saved. Every result? Every other result? etc... int outIntervalInt = 1; String outputInterval = experimentParameters.get(ModelicaKeys.OUTPUT_INTERVAL); if(outputInterval != null) { - String stepTime = experimentParameters.get(ModelicaKeys.STEP_VALUE); - String stopTime = experimentParameters.get(ModelicaKeys.STOP_VALUE); - - Double step = Double.parseDouble(stepTime); - Double stop = Double.parseDouble(stopTime); Double outInterval = Double.parseDouble(outputInterval); outIntervalInt = (int)getInterval(outInterval, step); // Actually you might be able to use an outInterval one or two longer. - int maxIntervalInt = (int)Math.round(stop / step); + int maxIntervalInt = (int)Math.round((stop - start) / step); if (outIntervalInt > maxIntervalInt) outIntervalInt = maxIntervalInt; } @@ -265,6 +268,7 @@ public class SysdynSensitivityAnalysisExperiment extends OldSysdynExperiment { currentResult.setResult(result); currentResult.setResultFile(resFile); currentResult.setResultIndex(currentRun); + currentResult.setFilter(start, stop, step); if(updateMonitors) resultsChanged(); -- 2.47.1