linny-r 1.6.8 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -88,7 +88,6 @@ class LinnyRModel {
88
88
  this.selected_round = 0;
89
89
 
90
90
  // Model settings
91
- this.timeout_period = 30; // max. solver time in seconds
92
91
  this.block_length = 1;
93
92
  this.start_period = 1; // defines starting point in datasets
94
93
  this.end_period = 1;
@@ -99,6 +98,12 @@ class LinnyRModel {
99
98
  this.report_results = false;
100
99
  this.show_block_arrows = true;
101
100
  this.last_zoom_factor = 1;
101
+
102
+ // Default solver settings
103
+ this.timeout_period = 30; // max. solver time in seconds
104
+ this.preferred_solver = ''; // empty string denotes "use default"
105
+ this.integer_tolerance = 5e-7; // integer feasibility tolerance
106
+ this.MIP_gap = 1e-4; // relative MIP gap
102
107
 
103
108
  // Sensitivity-related properties
104
109
  this.base_case_selectors = '';
@@ -140,17 +145,18 @@ class LinnyRModel {
140
145
  /* METHODS THAT LOOKUP ENTITIES, OR INFER PROPERTIES */
141
146
 
142
147
  get simulationTimeStep() {
143
- // Returns actual model time step, rather than `t`, which is relative to the
144
- // start of the simulation period
148
+ // Return actual model time step, rather than `t`, which is relative
149
+ // to the start of the simulation period.
145
150
  return this.t + this.start_period - 1;
146
151
  }
147
152
 
148
153
  get timeStepDuration() {
149
- // Returns duration of 1 time step in hours
154
+ // Return duration of 1 time step in hours.
150
155
  return this.time_scale * VM.time_unit_values[this.time_unit];
151
156
  }
152
157
 
153
158
  get outcomes() {
159
+ // Return the list of outcome datasets.
154
160
  const olist = [];
155
161
  for(let k in this.datasets) if(this.datasets.hasOwnProperty(k)) {
156
162
  if(this.datasets[k].outcome) olist.push(this.datasets[k]);
@@ -2631,17 +2637,17 @@ class LinnyRModel {
2631
2637
  }
2632
2638
 
2633
2639
  initFromXML(node) {
2634
- // Initialize a model from the XML tree with `node` as root
2635
- // NOTE: do NOT reset and initialize basic model properties when *including*
2636
- // a module into the current model
2637
- // NOTE: obsolete XML nodes indicate: legacy Linny-R model
2640
+ // Initialize a model from the XML tree with `node` as root.
2641
+ // NOTE: do NOT reset and initialize basic model properties when
2642
+ // *including* a module into the current model.
2643
+ // NOTE: Obsolete XML nodes indicate: legacy Linny-R model.
2638
2644
  const legacy_model = (nodeParameterValue(node, 'view-options') +
2639
2645
  nodeParameterValue(node, 'autosave') +
2640
2646
  nodeParameterValue(node, 'look-ahead') +
2641
2647
  nodeParameterValue(node, 'save-series') +
2642
2648
  nodeParameterValue(node, 'show-lp') +
2643
2649
  nodeParameterValue(node, 'optional-slack')).length > 0;
2644
- // Flag to set when legacy time series data are added
2650
+ // Flag to set when legacy time series data are added.
2645
2651
  this.legacy_datasets = false;
2646
2652
  if(!IO_CONTEXT) {
2647
2653
  this.reset();
@@ -2668,7 +2674,12 @@ class LinnyRModel {
2668
2674
  this.version = xmlDecoded(nodeContentByTag(node, 'version'));
2669
2675
  this.timeout_period = Math.max(0,
2670
2676
  safeStrToInt(nodeContentByTag(node, 'timeout-period')));
2671
- // Legacy models have tag "optimization-period" instead of "block-length"
2677
+ this.preferred_solver = xmlDecoded(
2678
+ nodeContentByTag(node, 'preferred-solver'));
2679
+ this.integer_tolerance = safeStrToFloat(
2680
+ nodeContentByTag(node, 'integer-tolerance'), 5e-7);
2681
+ this.MIP_gap = safeStrToFloat(nodeContentByTag(node, 'mip-gap'), 1e-4);
2682
+ // Legacy models have tag "optimization-period" instead of "block-length".
2672
2683
  const bl_str = nodeContentByTag(node, 'block-length') ||
2673
2684
  nodeContentByTag(node, 'optimization-period');
2674
2685
  this.block_length = Math.max(1, safeStrToInt(node, bl_str));
@@ -2693,7 +2704,7 @@ class LinnyRModel {
2693
2704
  if(!this.default_unit) this.default_unit = CONFIGURATION.default_scale_unit;
2694
2705
  } // END IF *not* including a model
2695
2706
 
2696
- // Declare some local variables that will be used a lot
2707
+ // Declare some local variables that will be used a lot.
2697
2708
  let i,
2698
2709
  c,
2699
2710
  name,
@@ -3014,7 +3025,10 @@ class LinnyRModel {
3014
3025
  '</default-scale-unit><currency-unit>', xmlEncoded(this.currency_unit),
3015
3026
  '</currency-unit><grid-pixels>', this.grid_pixels,
3016
3027
  '</grid-pixels><timeout-period>', this.timeout_period,
3017
- '</timeout-period><block-length>', this.block_length,
3028
+ '</timeout-period><preferred-solver>', xmlEncoded(this.preferred_solver),
3029
+ '</preferred-solver><integer-tolerance>', this.integer_tolerance,
3030
+ '</integer-tolerance><mip-gap>', this.MIP_gap,
3031
+ '</mip-gap><block-length>', this.block_length,
3018
3032
  '</block-length><start-period>', this.start_period,
3019
3033
  '</start-period><end-period>', this.end_period,
3020
3034
  '</end-period><look-ahead-period>', this.look_ahead,
@@ -2328,7 +2328,13 @@ class VirtualMachine {
2328
2328
  // Statistics that can be calculated for outcomes and experiment run results
2329
2329
  this.outcome_statistics =
2330
2330
  ['LAST', 'MAX', 'MEAN', 'MIN', 'N', 'NZ', 'SD', 'SUM', 'VAR'];
2331
- }
2331
+ this.solver_names = {
2332
+ gurobi: 'Gurobi',
2333
+ cplex: 'CPLEX',
2334
+ scip: 'SCIP',
2335
+ lp_solve: 'LP_solve'
2336
+ };
2337
+ }
2332
2338
 
2333
2339
  reset() {
2334
2340
  // Reset the virtual machine so that it can execute the model again.
@@ -2945,6 +2951,7 @@ class VirtualMachine {
2945
2951
  return obj.la_peak_inc[c];
2946
2952
  }
2947
2953
  const prior_level = obj.actualLevel(t);
2954
+ //console.log('HERE obj prilev t', obj.displayName, prior_level, t, obj.level);
2948
2955
  if(type === 'OO') return prior_level > 0 ? 1 : 0;
2949
2956
  if(type === 'IZ') return prior_level === 0 ? 1 : 0;
2950
2957
  // Start-up at time t entails that t is in the list of start-up
@@ -4305,7 +4312,7 @@ class VirtualMachine {
4305
4312
  // Return floating point number `n`, or +INF or -INF if the absolute
4306
4313
  // value of `n` is relatively (!) close to the VM infinity constants
4307
4314
  // (since the solver may return imprecise values of such magnitude).
4308
- if(n > 0.5 * VM.PLUS_INFINITY && n < VM.BEYOND_PLUS_INFINITY) {
4315
+ if(n > 0.5 * VM.PLUS_INFINITY && n < VM.BEYOND_PLUS_INFINITY) {
4309
4316
  return VM.PLUS_INFINITY;
4310
4317
  }
4311
4318
  if(n < 0.5 * VM.MINUS_INFINITY && n > VM.BEYOND_MINUS_INFINITY) {
@@ -5719,7 +5726,7 @@ Solver status = ${json.status}`);
5719
5726
  }
5720
5727
 
5721
5728
  submitFile() {
5722
- // Prepares to POST the model file (LP or MPS) to the Linny-R server.
5729
+ // Prepare to POST the model file (LP or MPS) to the Linny-R server.
5723
5730
  // NOTE: The tableau is no longer needed, so free up its memory.
5724
5731
  this.resetTableau();
5725
5732
  if(this.numeric_issue) {
@@ -5772,6 +5779,13 @@ Solver status = ${json.status}`);
5772
5779
  solveModel() {
5773
5780
  // Start the sequence of data loading, model translation, solving
5774
5781
  // consecutive blocks, and finally calculating dependent variables.
5782
+ // NOTE: Do this only if the model defines a MILP problem, i.e.,
5783
+ // contains at least one process or product.
5784
+ if(!(Object.keys(MODEL.processes).length ||
5785
+ Object.keys(MODEL.products).length)) {
5786
+ UI.notify('Nothing to solve');
5787
+ return;
5788
+ }
5775
5789
  const n = MODEL.loading_datasets.length;
5776
5790
  if(n > 0) {
5777
5791
  // Still within reasonable time? (3 seconds per dataset)
@@ -5780,7 +5794,7 @@ Solver status = ${json.status}`);
5780
5794
  UI.setMessage(`Waiting for ${pluralS(n, 'dataset')} to load`);
5781
5795
  // Decrease the remaining time to wait (half second units)
5782
5796
  MODEL.max_time_to_load--;
5783
- // Try again after half a second
5797
+ // Try again after half a second.
5784
5798
  setTimeout(() => VM.solveModel(), 500);
5785
5799
  return;
5786
5800
  } else {