linny-r 3.0.2 → 3.0.3
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.
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/server.js +1 -1
- package/static/index.html +13 -1
- package/static/linny-r-show-diff.css +1 -1
- package/static/linny-r.css +9 -4
- package/static/scripts/linny-r-config.js +5 -1
- package/static/scripts/linny-r-gui-actor-manager.js +1 -1
- package/static/scripts/linny-r-gui-chart-manager.js +1 -1
- package/static/scripts/linny-r-gui-constraint-editor.js +1 -1
- package/static/scripts/linny-r-gui-controller.js +5 -1
- package/static/scripts/linny-r-gui-dataset-manager.js +1 -1
- package/static/scripts/linny-r-gui-documentation-manager.js +1 -1
- package/static/scripts/linny-r-gui-equation-manager.js +1 -1
- package/static/scripts/linny-r-gui-expression-editor.js +1 -1
- package/static/scripts/linny-r-gui-file-manager.js +1 -1
- package/static/scripts/linny-r-gui-finder.js +1 -1
- package/static/scripts/linny-r-gui-monitor.js +1 -1
- package/static/scripts/linny-r-gui-paper.js +1 -1
- package/static/scripts/linny-r-gui-receiver.js +1 -1
- package/static/scripts/linny-r-gui-sensitivity-analysis.js +1 -1
- package/static/scripts/linny-r-gui-undo-redo.js +1 -1
- package/static/scripts/linny-r-milp.js +24 -12
- package/static/scripts/linny-r-model.js +6 -1
- package/static/scripts/linny-r-show-diff.js +1 -1
- package/static/scripts/linny-r-utils.js +1 -1
- package/static/scripts/linny-r-vm.js +19 -4
- package/static/show-diff.html +1 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 Delft University of Technology
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ These <a href="https://sysmod.tbm.tudelft.nl/linny-r/docs/?68"
|
|
|
23
23
|
an idea of what Linny-R can do.
|
|
24
24
|
|
|
25
25
|
User documentation for Linny-R is still scant. A book "Modelling and
|
|
26
|
-
simulation with Linny-R" will be published by TU Delft OPEN
|
|
26
|
+
simulation with Linny-R" will be published by TU Delft OPEN in 2026.
|
|
27
27
|
Meanwhile, you can consult the official user documentation site
|
|
28
28
|
<a href="https://linny-r.info" target="_blank">https://linny-r.info</a>.
|
|
29
29
|
Technical documentation will be developed in due time on GitHub:
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -12,7 +12,7 @@ that pass the MILP equation model to the solver, and then return the solution
|
|
|
12
12
|
to the Linny-R "virtual machine" that is running in the browser.
|
|
13
13
|
*/
|
|
14
14
|
/*
|
|
15
|
-
Copyright (c) 2020-
|
|
15
|
+
Copyright (c) 2020-2026 Delft University of Technology
|
|
16
16
|
|
|
17
17
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
18
18
|
of this software and associated documentation files (the "Software"), to deal
|
package/static/index.html
CHANGED
|
@@ -31,7 +31,7 @@ will be made available via GitHub in due time.
|
|
|
31
31
|
-->
|
|
32
32
|
|
|
33
33
|
<!--
|
|
34
|
-
Copyright (c) 2017-
|
|
34
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
35
35
|
|
|
36
36
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
37
37
|
a copy of this software and associated documentation files (the
|
|
@@ -326,6 +326,12 @@ will be written with decimal comma instead of decimal point.">
|
|
|
326
326
|
<div class="box-lbl">Use decimal <u>comma</u> when copying data</div>
|
|
327
327
|
</td>
|
|
328
328
|
</tr>
|
|
329
|
+
<tr title="Disabling semi-continuous variables may resolve “ghost” start-ups">
|
|
330
|
+
<td>
|
|
331
|
+
<div id="defaults-no-semi-continuous" class="box clear"></div>
|
|
332
|
+
<div class="box-lbl">Do not use semi-continuous variables</div>
|
|
333
|
+
</td>
|
|
334
|
+
</tr>
|
|
329
335
|
<tr title="When checked, small slack uses are reported in monitor">
|
|
330
336
|
<td>
|
|
331
337
|
<div id="defaults-show-notices" class="box checked"></div>
|
|
@@ -815,6 +821,12 @@ NOTE: Products directly linked to such processes should have a proportional unit
|
|
|
815
821
|
placeholder="1e-4" type="text" autocomplete="off">
|
|
816
822
|
</td>
|
|
817
823
|
</tr>
|
|
824
|
+
<tr title="Disabling semi-continuous variables may resolve “ghost” start-ups">
|
|
825
|
+
<td>
|
|
826
|
+
<div id="solver-no-semi-continuous" class="box clear"></div>
|
|
827
|
+
<div class="box-lbl">Do not use semi-continuous variables</div>
|
|
828
|
+
</td>
|
|
829
|
+
</tr>
|
|
818
830
|
<tr title="When checked, small slack uses are reported in monitor">
|
|
819
831
|
<td>
|
|
820
832
|
<div id="solver-show-notices" class="box clear"></div>
|
|
@@ -11,7 +11,7 @@ model (A) and another model (B) that is loaded by the File manager.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
package/static/linny-r.css
CHANGED
|
@@ -10,7 +10,7 @@ file that implements the graphical user interface for Linny-R.
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
/*
|
|
13
|
-
Copyright (c) 2017-
|
|
13
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
14
14
|
|
|
15
15
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
16
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1198,8 +1198,6 @@ table.power-flow th:not(:first-child) {
|
|
|
1198
1198
|
#settings-power,
|
|
1199
1199
|
#settings-cost-prices,
|
|
1200
1200
|
#settings-negative-flows,
|
|
1201
|
-
#defaults-comma,
|
|
1202
|
-
#defaults-show-notices,
|
|
1203
1201
|
#settings-decimal-comma,
|
|
1204
1202
|
#settings-report-results,
|
|
1205
1203
|
#settings-encrypt {
|
|
@@ -1230,7 +1228,7 @@ table.power-flow th:not(:first-child) {
|
|
|
1230
1228
|
}
|
|
1231
1229
|
|
|
1232
1230
|
#solver-dlg {
|
|
1233
|
-
width:
|
|
1231
|
+
width: 230px;
|
|
1234
1232
|
height: min-content;
|
|
1235
1233
|
}
|
|
1236
1234
|
|
|
@@ -1239,6 +1237,7 @@ table.power-flow th:not(:first-child) {
|
|
|
1239
1237
|
width: 65px;
|
|
1240
1238
|
}
|
|
1241
1239
|
|
|
1240
|
+
#solver-no-semi-continuous,
|
|
1242
1241
|
#solver-show-notices {
|
|
1243
1242
|
margin: 0;
|
|
1244
1243
|
}
|
|
@@ -1534,6 +1533,12 @@ div.export {
|
|
|
1534
1533
|
margin: 1px;
|
|
1535
1534
|
}
|
|
1536
1535
|
|
|
1536
|
+
#defaults-comma,
|
|
1537
|
+
#defaults-no-semi-continuous,
|
|
1538
|
+
#defaults-show-notices {
|
|
1539
|
+
margin: 0;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1537
1542
|
/* Styles for the MODEL and SAVE dialogs. */
|
|
1538
1543
|
#save-dlg,
|
|
1539
1544
|
#model-dlg {
|
|
@@ -11,7 +11,7 @@ warning or information messages are displayed.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -51,6 +51,10 @@ const CONFIGURATION = {
|
|
|
51
51
|
// will be written with decimal comma instead of decimal point.
|
|
52
52
|
// NOTE: May be overruled by model settings.
|
|
53
53
|
decimal_comma: false,
|
|
54
|
+
// By default, the VM will use semi-continuous variables to implement the
|
|
55
|
+
// "Shut down when lower bound constrains" option of processes.
|
|
56
|
+
// When disabled, sem-continuity is modeled using binary indicator variables.
|
|
57
|
+
no_semi_continuous: false,
|
|
54
58
|
// By default, the monitor will notify where and when small amounts of slack
|
|
55
59
|
// (< 1e-6) are used. Set to FALSE to suppress such notices).
|
|
56
60
|
slight_slack_notices: true,
|
|
@@ -11,7 +11,7 @@ functionality for the Linny-R Actor Manager dialog.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ for the Linny-R Chart Manager dialog.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ dialog for the Linny-R constraint editor.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -13,7 +13,7 @@ handler functions.
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/*
|
|
16
|
-
Copyright (c) 2017-
|
|
16
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
17
17
|
|
|
18
18
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
19
19
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1426,6 +1426,7 @@ class GUIController extends Controller {
|
|
|
1426
1426
|
md.element('time-unit').value = CONFIGURATION.default_time_unit;
|
|
1427
1427
|
md.element('scale-unit').value = CONFIGURATION.default_scale_unit;
|
|
1428
1428
|
this.setBox('defaults-comma', CONFIGURATION.decimal_comma);
|
|
1429
|
+
this.setBox('defaults-no-semi-continuous', CONFIGURATION.no_semi_continuous);
|
|
1429
1430
|
this.setBox('defaults-show-notices', CONFIGURATION.slight_slack_notices);
|
|
1430
1431
|
md.show('author');
|
|
1431
1432
|
}
|
|
@@ -1450,6 +1451,7 @@ class GUIController extends Controller {
|
|
|
1450
1451
|
default_time_unit: md.element('time-unit').value,
|
|
1451
1452
|
default_scale_unit: md.element('scale-unit').value.trim() || '1',
|
|
1452
1453
|
decimal_comma: this.boxChecked('defaults-comma'),
|
|
1454
|
+
no_semi_continuous: this.boxChecked('defaults-no-semi-continuous'),
|
|
1453
1455
|
slight_slack_notices: this.boxChecked('defaults-show-notices')
|
|
1454
1456
|
};
|
|
1455
1457
|
this.updateDefaults(JSON.stringify(d));
|
|
@@ -4331,6 +4333,7 @@ console.log('HERE name conflicts', name_conflicts, mapping);
|
|
|
4331
4333
|
md.element('preference').innerHTML = html.join('');
|
|
4332
4334
|
md.element('int-feasibility').value = MODEL.integer_tolerance;
|
|
4333
4335
|
md.element('mip-gap').value = MODEL.MIP_gap;
|
|
4336
|
+
this.setBox('solver-no-semi-continuous', MODEL.no_semi_continuous);
|
|
4334
4337
|
this.setBox('solver-show-notices', MODEL.show_notices);
|
|
4335
4338
|
md.show();
|
|
4336
4339
|
}
|
|
@@ -4360,6 +4363,7 @@ console.log('HERE name conflicts', name_conflicts, mapping);
|
|
|
4360
4363
|
}
|
|
4361
4364
|
MODEL.integer_tolerance = Math.max(1e-9, Math.min(0.1, itol));
|
|
4362
4365
|
MODEL.MIP_gap = Math.max(0, Math.min(0.5, mgap));
|
|
4366
|
+
MODEL.no_semi_continuous = this.boxChecked('solver-no-semi-continuous');
|
|
4363
4367
|
MODEL.show_notices = this.boxChecked('solver-show-notices');
|
|
4364
4368
|
// Close the dialog.
|
|
4365
4369
|
md.hide();
|
|
@@ -11,7 +11,7 @@ for the Linny-R Dataset Manager dialog.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -12,7 +12,7 @@ viewing and editing documentation text for model entities.
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/*
|
|
15
|
-
Copyright (c) 2017-
|
|
15
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
16
16
|
|
|
17
17
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
18
18
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ for the Linny-R Equation Manager dialog.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ functionality for the Linny-R Expression Editor dialog.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ functionality for the Linny-R File Manager.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -13,7 +13,7 @@ model.
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/*
|
|
16
|
-
Copyright (c) 2017-
|
|
16
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
17
17
|
|
|
18
18
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
19
19
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ for the Linny-R Monitor dialog.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ functionality for the Linny-R model editor.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -13,7 +13,7 @@ executed, perform this operation, and write report files to the user space.
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/*
|
|
16
|
-
Copyright (c) 2017-
|
|
16
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
17
17
|
|
|
18
18
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
19
19
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ for the Linny-R Sensitivity Analysis dialog.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -11,7 +11,7 @@ functionality for the Linny-R model editor.
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/*
|
|
14
|
-
Copyright (c) 2017-
|
|
14
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
15
15
|
|
|
16
16
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
17
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -14,7 +14,7 @@ NOTE: For browser-based Linny-R, this file should NOT be loaded, as it is
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
/*
|
|
17
|
-
Copyright (c) 2017-
|
|
17
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
18
18
|
|
|
19
19
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
20
20
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -41,6 +41,15 @@ const
|
|
|
41
41
|
os = require('os'),
|
|
42
42
|
path = require('path');
|
|
43
43
|
|
|
44
|
+
function safeTextToLines(s) {
|
|
45
|
+
// Return array of lines when `s` is split at the most likely EOL.
|
|
46
|
+
if(s.indexOf('\r\n') >= 0) {
|
|
47
|
+
return s.trim().split('\r\n');
|
|
48
|
+
} else {
|
|
49
|
+
return s.trim().split('\n');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
44
53
|
// Class MILPSolver implements the connection with the solver.
|
|
45
54
|
module.exports = class MILPSolver {
|
|
46
55
|
constructor(name, workspace) {
|
|
@@ -262,7 +271,7 @@ module.exports = class MILPSolver {
|
|
|
262
271
|
`-out "${s.solver_model}"`,
|
|
263
272
|
`-d MSK_DPAR_MIO_MAX_TIME %T%`,
|
|
264
273
|
`-d MSK_DPAR_MIO_TOL_ABS_RELAX_INT %I%`,
|
|
265
|
-
'-d
|
|
274
|
+
'-d MSK_DPAR_MIO_TOL_REL_GAP %M%',
|
|
266
275
|
`"${s.user_model}"`
|
|
267
276
|
];
|
|
268
277
|
s.solve_cmd = `mosek ${s.args.join(' ')} >${s.log}`;
|
|
@@ -624,7 +633,7 @@ module.exports = class MILPSolver {
|
|
|
624
633
|
// Solver output has different formats, hence separate routines.
|
|
625
634
|
if(this.id === 'gurobi') {
|
|
626
635
|
// `messages` must be an array of strings.
|
|
627
|
-
result.messages = log
|
|
636
|
+
result.messages = safeTextToLines(log);
|
|
628
637
|
if(result.status === 1 ||
|
|
629
638
|
(result.status !== 0 && log.indexOf('license') < 0)) {
|
|
630
639
|
// Exit code typically indicates expired license, but also
|
|
@@ -670,7 +679,7 @@ module.exports = class MILPSolver {
|
|
|
670
679
|
let solved = false,
|
|
671
680
|
output = [];
|
|
672
681
|
// `messages` must be an array of strings.
|
|
673
|
-
result.messages = log
|
|
682
|
+
result.messages = safeTextToLines(log);
|
|
674
683
|
// NOTE: MOSEK may also write solution to 'user_model.bas', so
|
|
675
684
|
// try that as well before reporting failure.
|
|
676
685
|
try {
|
|
@@ -687,7 +696,7 @@ module.exports = class MILPSolver {
|
|
|
687
696
|
console.log('No MOSEK solution file');
|
|
688
697
|
} else if(output.indexOf('SOLUTION STATUS') >= 0) {
|
|
689
698
|
solved = true;
|
|
690
|
-
output = output
|
|
699
|
+
output = safeTextToLines(output);
|
|
691
700
|
}
|
|
692
701
|
if(solved) {
|
|
693
702
|
// MOSEK saves solution in a proprietary format, so just extract
|
|
@@ -702,7 +711,10 @@ module.exports = class MILPSolver {
|
|
|
702
711
|
}
|
|
703
712
|
i++;
|
|
704
713
|
}
|
|
705
|
-
if(result.status
|
|
714
|
+
if(result.status === undefined) {
|
|
715
|
+
result.error = 'No status found in MOSEK solution file';
|
|
716
|
+
solved = false;
|
|
717
|
+
} else if(result.status.indexOf('OPTIMAL') >= 0) {
|
|
706
718
|
result.status = 0;
|
|
707
719
|
result.error = '';
|
|
708
720
|
} else if(result.status.indexOf('DUAL_INFEASIBLE') >= 0) {
|
|
@@ -747,7 +759,7 @@ module.exports = class MILPSolver {
|
|
|
747
759
|
mst = log.match(/Solution time \=\s+(\d+\.\d+) sec/);
|
|
748
760
|
if(mst && mst.length > 1) result.seconds = parseFloat(mst[1]);
|
|
749
761
|
// `messages` must be an array of strings.
|
|
750
|
-
result.messages = log
|
|
762
|
+
result.messages = safeTextToLines(log);
|
|
751
763
|
let solved = false,
|
|
752
764
|
output = [];
|
|
753
765
|
if(no_license) {
|
|
@@ -771,7 +783,7 @@ module.exports = class MILPSolver {
|
|
|
771
783
|
output = fs.readFileSync(s.solution, 'utf8').trim();
|
|
772
784
|
if(output.indexOf('CPLEXSolution') >= 0) {
|
|
773
785
|
solved = true;
|
|
774
|
-
output = output
|
|
786
|
+
output = safeTextToLines(output);
|
|
775
787
|
}
|
|
776
788
|
} catch(err) {
|
|
777
789
|
console.log('No CPLEX solution file');
|
|
@@ -813,7 +825,7 @@ module.exports = class MILPSolver {
|
|
|
813
825
|
} else if(this.id === 'scip') {
|
|
814
826
|
result.seconds = 0;
|
|
815
827
|
// `messages` must be an array of strings.
|
|
816
|
-
result.messages = log
|
|
828
|
+
result.messages = safeTextToLines(log);
|
|
817
829
|
let solved = false,
|
|
818
830
|
output = [];
|
|
819
831
|
if(result.status !== 0) {
|
|
@@ -821,8 +833,8 @@ module.exports = class MILPSolver {
|
|
|
821
833
|
result.error = 'SCIP solver terminated with error';
|
|
822
834
|
} else {
|
|
823
835
|
try {
|
|
824
|
-
output =
|
|
825
|
-
s.solution, 'utf8').trim()
|
|
836
|
+
output = safeTextToLines(
|
|
837
|
+
fs.readFileSync(s.solution, 'utf8').trim());
|
|
826
838
|
} catch(err) {
|
|
827
839
|
console.log('No SCIP solution file');
|
|
828
840
|
}
|
|
@@ -877,7 +889,7 @@ module.exports = class MILPSolver {
|
|
|
877
889
|
const
|
|
878
890
|
// NOTE: LP_solve both messages and solution console, hence
|
|
879
891
|
// the log file is processed in two "stages".
|
|
880
|
-
output = log
|
|
892
|
+
output = safeTextToLines(log),
|
|
881
893
|
// NOTE: Linny-R client expects log messages as list of strings.
|
|
882
894
|
msgs = [];
|
|
883
895
|
result.seconds = 0;
|
|
@@ -10,7 +10,7 @@ the Linny-R project.
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
/*
|
|
13
|
-
Copyright (c) 2017-
|
|
13
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
14
14
|
|
|
15
15
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
16
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -54,11 +54,14 @@ class LinnyRModel {
|
|
|
54
54
|
// determine whether the last undo/redo occurred *after* the last save.
|
|
55
55
|
this.last_modified = d;
|
|
56
56
|
this.version = LINNY_R_VERSION;
|
|
57
|
+
// Initial defaults are defined in the configuration script, but can be
|
|
58
|
+
// superseded by defaults read from the user workspace by the server.
|
|
57
59
|
this.time_scale = CONFIGURATION.default_time_scale;
|
|
58
60
|
this.time_unit = CONFIGURATION.default_time_unit;
|
|
59
61
|
this.currency_unit = CONFIGURATION.default_currency_unit;
|
|
60
62
|
this.default_unit = CONFIGURATION.default_scale_unit;
|
|
61
63
|
this.decimal_comma = CONFIGURATION.decimal_comma;
|
|
64
|
+
this.no_semi_continuous = CONFIGURATION.no_semi_continuous;
|
|
62
65
|
// NOTE: Default scale unit list comprises only the primitive base unit.
|
|
63
66
|
this.scale_units = {'1': new ScaleUnit('1', '1', '1')};
|
|
64
67
|
this.power_grids = {};
|
|
@@ -2990,6 +2993,7 @@ class LinnyRModel {
|
|
|
2990
2993
|
this.show_block_arrows = nodeParameterValue(node, 'block-arrows') === '1';
|
|
2991
2994
|
// NOTE: Diagnosis option should default to TRUE unless *set* to FALSE.
|
|
2992
2995
|
this.always_diagnose = nodeParameterValue(node, 'diagnose') !== '0';
|
|
2996
|
+
this.no_semi_continuous = nodeParameterValue(node, 'no-semi-continuous') === '1';
|
|
2993
2997
|
this.show_notices = nodeParameterValue(node, 'show-notices') === '1';
|
|
2994
2998
|
this.name = xmlDecoded(nodeContentByTag(node, 'name'));
|
|
2995
2999
|
this.author = xmlDecoded(nodeContentByTag(node, 'author'));
|
|
@@ -3368,6 +3372,7 @@ class LinnyRModel {
|
|
|
3368
3372
|
if(this.infer_cost_prices) p += ' cost-prices="1"';
|
|
3369
3373
|
if(this.report_results) p += ' report-results="1"';
|
|
3370
3374
|
if(this.show_block_arrows) p += ' block-arrows="1"';
|
|
3375
|
+
if(this.no_semi_continuous) p += ' no-semi-continuous="1"';
|
|
3371
3376
|
if(this.show_notices) p += ' show-notices="1"';
|
|
3372
3377
|
let xml = this.xml_header + ['<model', p, '><name>', xmlEncoded(this.name),
|
|
3373
3378
|
'</name><author>', xmlEncoded(this.author),
|
|
@@ -12,7 +12,7 @@ by the File manager after comparing the current model (A) with another model
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/*
|
|
15
|
-
Copyright (c) 2017-
|
|
15
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
16
16
|
|
|
17
17
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
18
18
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -9,7 +9,7 @@ This JavaScript file (linny-r-utils.js) defines a variety of "helper" functions
|
|
|
9
9
|
that are used in other Linny-R modules.
|
|
10
10
|
*/
|
|
11
11
|
/*
|
|
12
|
-
Copyright (c) 2017-
|
|
12
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
13
13
|
|
|
14
14
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
15
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -12,7 +12,7 @@ executed by the VM, construct the Simplex tableau that can be sent to the
|
|
|
12
12
|
MILP solver.
|
|
13
13
|
*/
|
|
14
14
|
/*
|
|
15
|
-
Copyright (c) 2017-
|
|
15
|
+
Copyright (c) 2017-2026 Delft University of Technology
|
|
16
16
|
|
|
17
17
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
18
18
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -2238,7 +2238,7 @@ class VirtualMachine {
|
|
|
2238
2238
|
// NOTE: For smaller values than 5e-6, Gurobi will not compute ON/OFF
|
|
2239
2239
|
// binaries correctly, as it then accepts this low value as a violation
|
|
2240
2240
|
// constraint.
|
|
2241
|
-
this.ON_OFF_THRESHOLD =
|
|
2241
|
+
this.ON_OFF_THRESHOLD = 1e-5;
|
|
2242
2242
|
// Limit for upper bounds beyond which binaries cannot be computed
|
|
2243
2243
|
// correctly. Modeler is warned when this occurs (typically when
|
|
2244
2244
|
// ON/OFF variables are needed for a process having infinite bounds.
|
|
@@ -2478,7 +2478,7 @@ class VirtualMachine {
|
|
|
2478
2478
|
// Return TRUE if the selected solver does NOT support semi-continuous
|
|
2479
2479
|
// variables (used to implement "shut down when lower bound constraints"
|
|
2480
2480
|
// for processes).
|
|
2481
|
-
return this.solver_id === 'mosek';
|
|
2481
|
+
return this.solver_id === 'mosek' || MODEL.no_semi_continuous;
|
|
2482
2482
|
}
|
|
2483
2483
|
|
|
2484
2484
|
get noSupportForSOS() {
|
|
@@ -3895,7 +3895,8 @@ class VirtualMachine {
|
|
|
3895
3895
|
// NEXT: Add semi-continuous constraints only if not supported by solver.
|
|
3896
3896
|
if(this.noSemiContinuous) {
|
|
3897
3897
|
for(const k of process_keys) if(!MODEL.ignored_entities[k]) {
|
|
3898
|
-
|
|
3898
|
+
const p = MODEL.processes[k];
|
|
3899
|
+
if(p.level_to_zero) this.code.push([VMI_add_semicontinuous_constraints, p]);
|
|
3899
3900
|
}
|
|
3900
3901
|
}
|
|
3901
3902
|
|
|
@@ -4535,6 +4536,7 @@ class VirtualMachine {
|
|
|
4535
4536
|
this.plus_eps_sum = 0;
|
|
4536
4537
|
this.minus_eps_count = 0;
|
|
4537
4538
|
this.minus_eps_sum = 0;
|
|
4539
|
+
let ghost_su_count = 0;
|
|
4538
4540
|
// Set production levels and start-up moments for all processes.
|
|
4539
4541
|
for(let k in MODEL.processes) if(MODEL.processes.hasOwnProperty(k) &&
|
|
4540
4542
|
!MODEL.ignored_entities[k]) {
|
|
@@ -4578,6 +4580,11 @@ class VirtualMachine {
|
|
|
4578
4580
|
if(has_SU) {
|
|
4579
4581
|
if(x[p.start_up_var_index + j] > 0.999) {
|
|
4580
4582
|
p.start_ups.push(b);
|
|
4583
|
+
if(Math.abs(p.level[b]) <= this.ON_OFF_THRESHOLD) {
|
|
4584
|
+
this.logMessage(block, `${this.WARNING}(t=${b}${round}) ` +
|
|
4585
|
+
'Ghost start-up for process ' + p.displayName);
|
|
4586
|
+
ghost_su_count++;
|
|
4587
|
+
}
|
|
4581
4588
|
}
|
|
4582
4589
|
}
|
|
4583
4590
|
if(has_SD) {
|
|
@@ -4637,6 +4644,11 @@ class VirtualMachine {
|
|
|
4637
4644
|
if(has_SU) {
|
|
4638
4645
|
if(x[p.start_up_var_index + j] > 0.999) {
|
|
4639
4646
|
p.start_ups.push(b);
|
|
4647
|
+
if(Math.abs(p.level[b]) <= this.ON_OFF_THRESHOLD) {
|
|
4648
|
+
this.logMessage(block, `${this.WARNING}(t=${b}${round}) ` +
|
|
4649
|
+
'Ghost start-up for product ' + p.displayName);
|
|
4650
|
+
ghost_su_count++;
|
|
4651
|
+
}
|
|
4640
4652
|
}
|
|
4641
4653
|
}
|
|
4642
4654
|
// Same for shut-down variable.
|
|
@@ -4659,6 +4671,9 @@ class VirtualMachine {
|
|
|
4659
4671
|
b++;
|
|
4660
4672
|
}
|
|
4661
4673
|
}
|
|
4674
|
+
if(ghost_su_count) this.logMessage(block,
|
|
4675
|
+
'\nGhost start-ups may be suppressed via Model settings > Solver preferences' +
|
|
4676
|
+
'\nby checking the option "Do not use semi-continuous variables".\n');
|
|
4662
4677
|
// Get values of peak increase variables from solution vector.
|
|
4663
4678
|
// NOTE: Computed offset takes into account that chunk variable list
|
|
4664
4679
|
// is zero-based!
|
package/static/show-diff.html
CHANGED
|
@@ -13,7 +13,7 @@ displays it as part of this document.
|
|
|
13
13
|
-->
|
|
14
14
|
|
|
15
15
|
<!--
|
|
16
|
-
Copyright (c) 2022-
|
|
16
|
+
Copyright (c) 2022-2026 Delft University of Technology
|
|
17
17
|
|
|
18
18
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
19
19
|
of this software and associated documentation files (the "Software"), to deal
|