@abi-software/simulationvuer 3.0.1 → 3.0.2
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/dist/index-DtImQ0dj.js +83690 -0
- package/dist/{quill-CuAVUOyy-B7CbeCk7.js → quill-c3wy0V4g-xOU6dJmZ.js} +5 -8
- package/dist/simulationvuer.js +2 -70205
- package/dist/simulationvuer.umd.cjs +433 -292
- package/dist/style.css +1 -1
- package/package.json +3 -2
- package/src/components/SimulationVuer.vue +20 -217
- package/src/components/common.js +0 -9
- package/src/components/json.js +51 -53
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abi-software/simulationvuer",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"serve": "vite serve --host --force",
|
|
@@ -18,9 +18,10 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@abi-software/plotvuer": "1.0.7",
|
|
21
|
-
"@opencor/opencor": "^0.
|
|
21
|
+
"@opencor/opencor": "^0.20251205.0",
|
|
22
22
|
"element-plus": "2.8.4",
|
|
23
23
|
"jsonschema": "^1.4.0",
|
|
24
|
+
"mathjs": "^15.1.0",
|
|
24
25
|
"unplugin-vue-components": "^0.26.0",
|
|
25
26
|
"vue": "^3.4.21"
|
|
26
27
|
},
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
<div class="container" v-if="opencorOmexFile === null">
|
|
4
4
|
<p v-if="!hasValidSimulationUiInfo && !showUserMessage" class="default error"><span class="error">Error:</span> {{ errorMessage }}.</p>
|
|
5
5
|
<div class="main" v-if="hasValidSimulationUiInfo">
|
|
6
|
-
<div class="main-left" :class="{'with-buttons':
|
|
7
|
-
<p class="default name"
|
|
8
|
-
<el-divider
|
|
6
|
+
<div class="main-left" :class="{'with-buttons': uuid}">
|
|
7
|
+
<p class="default name">{{ name }}</p>
|
|
8
|
+
<el-divider></el-divider>
|
|
9
9
|
<p class="default input-parameters">Input parameters</p>
|
|
10
10
|
<div class="input scrollbar">
|
|
11
11
|
<SimulationVuerInput v-for="(input, index) in simulationUiInfo.input"
|
|
@@ -20,18 +20,15 @@
|
|
|
20
20
|
/>
|
|
21
21
|
</div>
|
|
22
22
|
<div class="buttons-container">
|
|
23
|
-
<div class="primary-button"
|
|
23
|
+
<div class="primary-button">
|
|
24
24
|
<el-button type="primary" size="small" @click="startSimulation()">Run Simulation</el-button>
|
|
25
25
|
</div>
|
|
26
26
|
<div class="secondary-button" v-if="uuid">
|
|
27
27
|
<el-button size="small" @click="runOnOsparc()">Run on oSPARC</el-button>
|
|
28
28
|
</div>
|
|
29
|
-
<div class="secondary-button"
|
|
29
|
+
<div class="secondary-button">
|
|
30
30
|
<el-button size="small" @click="viewDataset()">View Dataset</el-button>
|
|
31
31
|
</div>
|
|
32
|
-
<div class="secondary-button" v-if="libopencorSet && idType === 'pmr_path'">
|
|
33
|
-
<el-button size="small" @click="viewWorkspace()">View Workspace</el-button>
|
|
34
|
-
</div>
|
|
35
32
|
<p class="default note" v-if="uuid">Additional parameters are available on oSPARC</p>
|
|
36
33
|
</div>
|
|
37
34
|
</div>
|
|
@@ -63,7 +60,6 @@ import SimulationVuerInput from "./SimulationVuerInput.vue";
|
|
|
63
60
|
import { ElButton, ElDivider, ElLoading } from "element-plus";
|
|
64
61
|
import { evaluateValue, finaliseUi, OPENCOR_SOLVER_NAME } from "./common.js";
|
|
65
62
|
import { validJson } from "./json.js";
|
|
66
|
-
import libOpenCOR from "https://mapcore-demo.org/current/opencor-wasm/0.0.3/libopencor.js";
|
|
67
63
|
import { markRaw } from "vue";
|
|
68
64
|
import { create, all } from "mathjs";
|
|
69
65
|
import OpenCOR from '@opencor/opencor';
|
|
@@ -157,8 +153,6 @@ export default {
|
|
|
157
153
|
isMounted: false,
|
|
158
154
|
isSimulationValid: true,
|
|
159
155
|
layout: [],
|
|
160
|
-
libopencor: undefined,
|
|
161
|
-
libopencorSet: false,
|
|
162
156
|
model: undefined,
|
|
163
157
|
name: null,
|
|
164
158
|
opencorBasedSimulation: true,
|
|
@@ -193,150 +187,6 @@ export default {
|
|
|
193
187
|
},
|
|
194
188
|
};
|
|
195
189
|
},
|
|
196
|
-
/**
|
|
197
|
-
* @public
|
|
198
|
-
* Manage the file associated with the given `url` and `fileContents`.
|
|
199
|
-
* @arg `url`
|
|
200
|
-
* @arg `fileContents`
|
|
201
|
-
*/
|
|
202
|
-
manageFile(url, fileContents) {
|
|
203
|
-
let file = this.fileManager.file(url);
|
|
204
|
-
|
|
205
|
-
if (file === null) {
|
|
206
|
-
file = new this.libopencor.File(url);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const fileContentsPtr = this.libopencor._malloc(fileContents.length);
|
|
210
|
-
const mem = new Uint8Array(this.libopencor.HEAPU8.buffer, fileContentsPtr, fileContents.length);
|
|
211
|
-
|
|
212
|
-
mem.set(fileContents);
|
|
213
|
-
|
|
214
|
-
file.setContents(fileContentsPtr, fileContents.length);
|
|
215
|
-
|
|
216
|
-
this.libopencor._free(fileContentsPtr);
|
|
217
|
-
|
|
218
|
-
return file;
|
|
219
|
-
},
|
|
220
|
-
/**
|
|
221
|
-
* @public
|
|
222
|
-
* Run a PMR-based COMBINE archive using libOpenCOR.
|
|
223
|
-
*/
|
|
224
|
-
runSimulation() {
|
|
225
|
-
if (this.instance === undefined) {
|
|
226
|
-
// Retrieve an instance of the model.
|
|
227
|
-
|
|
228
|
-
const document = new this.libopencor.SedDocument(this.fileManager.file(PMR_URL + this.id));
|
|
229
|
-
|
|
230
|
-
this.model = markRaw(document.model());
|
|
231
|
-
this.instance = markRaw(document.instantiate());
|
|
232
|
-
|
|
233
|
-
document.delete();
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Run the simulation after passing some changes, if any, to the model.
|
|
237
|
-
|
|
238
|
-
this.model.removeAllChanges();
|
|
239
|
-
|
|
240
|
-
for (const [parameter, value] of Object.entries(this.parametersData())) {
|
|
241
|
-
const parameterParts = parameter.split("/")
|
|
242
|
-
|
|
243
|
-
this.model.addChange(new this.libopencor.SedChangeAttribute(parameterParts[0], parameterParts[1], value.toString()));
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
this.instance.run();
|
|
247
|
-
|
|
248
|
-
// Retrieve the simulation results.
|
|
249
|
-
|
|
250
|
-
const res = {};
|
|
251
|
-
const instanceTask = this.instance.task(0);
|
|
252
|
-
let foundAllOutputs = true;
|
|
253
|
-
let foundOutput;
|
|
254
|
-
|
|
255
|
-
for (const output of this.outputData()) {
|
|
256
|
-
foundOutput = false;
|
|
257
|
-
|
|
258
|
-
if (output === instanceTask.voiName) {
|
|
259
|
-
res[output] = instanceTask.voiAsArray;
|
|
260
|
-
|
|
261
|
-
foundOutput = true;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (res[output] === undefined) {
|
|
265
|
-
for (let i = 0; i < instanceTask.stateCount; ++i) {
|
|
266
|
-
if (output === instanceTask.stateName(i)) {
|
|
267
|
-
res[output] = instanceTask.stateAsArray(i);
|
|
268
|
-
|
|
269
|
-
foundOutput = true;
|
|
270
|
-
|
|
271
|
-
break;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (res[output] === undefined) {
|
|
277
|
-
for (let i = 0; i < instanceTask.rateCount; ++i) {
|
|
278
|
-
if (output === instanceTask.rateName(i)) {
|
|
279
|
-
res[output] = instanceTask.rateAsArray(i);
|
|
280
|
-
|
|
281
|
-
foundOutput = true;
|
|
282
|
-
|
|
283
|
-
break;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (res[output] === undefined) {
|
|
289
|
-
for (let i = 0; i < instanceTask.constantCount; ++i) {
|
|
290
|
-
if (output === instanceTask.constantName(i)) {
|
|
291
|
-
res[output] = instanceTask.constantAsArray(i);
|
|
292
|
-
|
|
293
|
-
foundOutput = true;
|
|
294
|
-
|
|
295
|
-
break;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (res[output] === undefined) {
|
|
301
|
-
for (let i = 0; i < instanceTask.computedConstantCount; ++i) {
|
|
302
|
-
if (output === instanceTask.computedConstantName(i)) {
|
|
303
|
-
res[output] = instanceTask.computedConstantAsArray(i);
|
|
304
|
-
|
|
305
|
-
foundOutput = true;
|
|
306
|
-
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
if (res[output] === undefined) {
|
|
313
|
-
for (let i = 0; i < instanceTask.algebraicCount; ++i) {
|
|
314
|
-
if (output === instanceTask.algebraicName(i)) {
|
|
315
|
-
res[output] = instanceTask.algebraicAsArray(i);
|
|
316
|
-
|
|
317
|
-
foundOutput = true;
|
|
318
|
-
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (!foundOutput) {
|
|
325
|
-
console.warn("SIMULATION: output '" + output + "' could not be found.");
|
|
326
|
-
|
|
327
|
-
foundAllOutputs = false;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (foundAllOutputs) {
|
|
332
|
-
this.processSimulationResults(res);
|
|
333
|
-
} else {
|
|
334
|
-
this.hasValidSimulationUiInfo = false;
|
|
335
|
-
this.errorMessage = "some outputs could not be found";
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
this.showUserMessage = false;
|
|
339
|
-
},
|
|
340
190
|
/**
|
|
341
191
|
* @public
|
|
342
192
|
* Build the simulation UI using `simulationUiInfo`, a JSON object that describes the contents of the simulation UI.
|
|
@@ -349,7 +199,7 @@ export default {
|
|
|
349
199
|
|
|
350
200
|
// Make sure that the simulation UI information is valid.
|
|
351
201
|
|
|
352
|
-
this.hasValidSimulationUiInfo = validJson(this.simulationUiInfo
|
|
202
|
+
this.hasValidSimulationUiInfo = validJson(this.simulationUiInfo);
|
|
353
203
|
|
|
354
204
|
if (!this.hasValidSimulationUiInfo) {
|
|
355
205
|
this.errorMessage = "the simulation.json file is malformed";
|
|
@@ -357,26 +207,23 @@ export default {
|
|
|
357
207
|
return;
|
|
358
208
|
}
|
|
359
209
|
|
|
360
|
-
// Retrieve and keep track of the solver to be used for the simulation
|
|
361
|
-
// needed.
|
|
362
|
-
|
|
363
|
-
if (this.libopencor === undefined) {
|
|
364
|
-
this.simulationUiInfo.simulation.solvers.forEach((solver) => {
|
|
365
|
-
if ((solver.if === undefined) || evaluateValue(this, solver.if)) {
|
|
366
|
-
this.solver = solver;
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
if (this.solver === undefined) {
|
|
371
|
-
this.hasValidSimulationUiInfo = false;
|
|
372
|
-
this.errorMessage = "no solver name and/or solver version specified";
|
|
210
|
+
// Retrieve and keep track of the solver to be used for the simulation.
|
|
373
211
|
|
|
374
|
-
|
|
212
|
+
this.simulationUiInfo.simulation.solvers.forEach((solver) => {
|
|
213
|
+
if ((solver.if === undefined) || evaluateValue(this, solver.if)) {
|
|
214
|
+
this.solver = solver;
|
|
375
215
|
}
|
|
216
|
+
});
|
|
376
217
|
|
|
377
|
-
|
|
218
|
+
if (this.solver === undefined) {
|
|
219
|
+
this.hasValidSimulationUiInfo = false;
|
|
220
|
+
this.errorMessage = "no solver name and/or solver version specified";
|
|
221
|
+
|
|
222
|
+
return;
|
|
378
223
|
}
|
|
379
224
|
|
|
225
|
+
this.opencorBasedSimulation = this.solver.name === OPENCOR_SOLVER_NAME;
|
|
226
|
+
|
|
380
227
|
// Initialise our UI.
|
|
381
228
|
|
|
382
229
|
this.simulationUiInfo.output.data.forEach((data) => {
|
|
@@ -433,40 +280,6 @@ export default {
|
|
|
433
280
|
finaliseUi(this);
|
|
434
281
|
});
|
|
435
282
|
},
|
|
436
|
-
/**
|
|
437
|
-
* @public
|
|
438
|
-
* Extract the simulation UI JSON file from the given file contents and build the simulation UI.
|
|
439
|
-
* @arg `libopencor`
|
|
440
|
-
* @arg `fileContents`
|
|
441
|
-
*/
|
|
442
|
-
extractAndBuildSimulationUi(libopencor, fileContents) {
|
|
443
|
-
this.libopencor = markRaw(libopencor);
|
|
444
|
-
this.libopencorSet = true;
|
|
445
|
-
this.fileManager = markRaw(this.libopencor.FileManager.instance());
|
|
446
|
-
|
|
447
|
-
const file = this.manageFile(PMR_URL + this.id, fileContents);
|
|
448
|
-
|
|
449
|
-
if (file.type.value !== libopencor.File.Type.COMBINE_ARCHIVE.value) {
|
|
450
|
-
this.showUserMessage = false;
|
|
451
|
-
} else {
|
|
452
|
-
const decoder = new TextDecoder();
|
|
453
|
-
const simulationJson = file.childFileFromFileName("simulation.json");
|
|
454
|
-
|
|
455
|
-
if (simulationJson === null) {
|
|
456
|
-
this.errorMessage = "no simulation JSON file could be found";
|
|
457
|
-
|
|
458
|
-
this.showUserMessage = false;
|
|
459
|
-
} else {
|
|
460
|
-
const simulationUiInfo = JSON.parse(decoder.decode(simulationJson.contents()));
|
|
461
|
-
|
|
462
|
-
this.showUserMessage = false;
|
|
463
|
-
|
|
464
|
-
this.$nextTick(() => {
|
|
465
|
-
this.buildSimulationUi(simulationUiInfo);
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
},
|
|
470
283
|
/**
|
|
471
284
|
* @public
|
|
472
285
|
* Run the simulation-based dataset directly on oSPARC. Not all simulation-based datasets can be run directly on
|
|
@@ -749,18 +562,8 @@ export default {
|
|
|
749
562
|
this.opencorOmexFile = this.id;
|
|
750
563
|
} else if (this.idType === IdType.PMR_PATH) {
|
|
751
564
|
this.opencorOmexFile = PMR_URL + this.id;
|
|
752
|
-
} else {
|
|
753
|
-
|
|
754
|
-
// the simulation UI.
|
|
755
|
-
|
|
756
|
-
this.userMessage = "Retrieving COMBINE archive...";
|
|
757
|
-
this.showUserMessage = true;
|
|
758
|
-
|
|
759
|
-
this.$nextTick(() => {
|
|
760
|
-
libOpenCOR().then((libopencor) => {
|
|
761
|
-
this.extractAndBuildSimulationUi(libopencor, this.id);
|
|
762
|
-
});
|
|
763
|
-
});
|
|
565
|
+
} else { // IdType.RAW_COMBINE_ARCHIVE
|
|
566
|
+
this.opencorOmexFile = this.id;
|
|
764
567
|
}
|
|
765
568
|
},
|
|
766
569
|
mounted: function () {
|
package/src/components/common.js
CHANGED
|
@@ -28,15 +28,6 @@ export function updateUi(parent) {
|
|
|
28
28
|
|
|
29
29
|
parent.$refs.simInput[index].visible = (input.visible === undefined) ? true : evaluateValue(parent, input.visible);
|
|
30
30
|
});
|
|
31
|
-
|
|
32
|
-
if (parent.libopencor !== undefined) {
|
|
33
|
-
parent.userMessage = "Running the model...";
|
|
34
|
-
parent.showUserMessage = true;
|
|
35
|
-
|
|
36
|
-
parent.$nextTick(() => {
|
|
37
|
-
parent.runSimulation();
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
31
|
});
|
|
41
32
|
}
|
|
42
33
|
|
package/src/components/json.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Validator } from "jsonschema";
|
|
2
2
|
import { OPENCOR_SOLVER_NAME } from "./common.js";
|
|
3
3
|
|
|
4
|
-
export function validJson(json
|
|
4
|
+
export function validJson(json) {
|
|
5
5
|
// Check the JSON against our schema.
|
|
6
6
|
|
|
7
7
|
const validator = new Validator();
|
|
@@ -214,7 +214,7 @@ export function validJson(json, simulationInfoNeeded) {
|
|
|
214
214
|
type: "array",
|
|
215
215
|
},
|
|
216
216
|
},
|
|
217
|
-
required:
|
|
217
|
+
required: true,
|
|
218
218
|
type: "object",
|
|
219
219
|
},
|
|
220
220
|
},
|
|
@@ -436,87 +436,85 @@ export function validJson(json, simulationInfoNeeded) {
|
|
|
436
436
|
|
|
437
437
|
// Make sure that the simulation information makes sense.
|
|
438
438
|
|
|
439
|
-
|
|
440
|
-
let needOpencorSettings = false;
|
|
441
|
-
|
|
442
|
-
if (!json.simulation.solvers.every((solver) => {
|
|
443
|
-
if (solver.if !== undefined) {
|
|
444
|
-
if (solver.if === "") {
|
|
445
|
-
console.warn("JSON: a simulation solver if must not be empty.");
|
|
446
|
-
|
|
447
|
-
return false;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
if (solver.input !== undefined) {
|
|
452
|
-
if (solver.input.name === "") {
|
|
453
|
-
console.warn("JSON: a simulation solver input name must not be empty.");
|
|
454
|
-
|
|
455
|
-
return false;
|
|
456
|
-
}
|
|
439
|
+
let needOpencorSettings = false;
|
|
457
440
|
|
|
458
|
-
|
|
459
|
-
|
|
441
|
+
if (!json.simulation.solvers.every((solver) => {
|
|
442
|
+
if (solver.if !== undefined) {
|
|
443
|
+
if (solver.if === "") {
|
|
444
|
+
console.warn("JSON: a simulation solver if must not be empty.");
|
|
460
445
|
|
|
461
|
-
|
|
462
|
-
}
|
|
446
|
+
return false;
|
|
463
447
|
}
|
|
448
|
+
}
|
|
464
449
|
|
|
465
|
-
|
|
466
|
-
|
|
450
|
+
if (solver.input !== undefined) {
|
|
451
|
+
if (solver.input.name === "") {
|
|
452
|
+
console.warn("JSON: a simulation solver input name must not be empty.");
|
|
467
453
|
|
|
468
454
|
return false;
|
|
469
455
|
}
|
|
470
456
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (solver.version === "") {
|
|
474
|
-
console.warn("JSON: a simulation solver version must not be empty.");
|
|
457
|
+
if (solver.input.value === "") {
|
|
458
|
+
console.warn("JSON: a simulation solver input value must not be empty.");
|
|
475
459
|
|
|
476
460
|
return false;
|
|
477
461
|
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (solver.name === "") {
|
|
465
|
+
console.warn("JSON: a simulation solver name must not be empty.");
|
|
478
466
|
|
|
479
|
-
return true;
|
|
480
|
-
})) {
|
|
481
467
|
return false;
|
|
482
468
|
}
|
|
483
469
|
|
|
484
|
-
|
|
485
|
-
|
|
470
|
+
needOpencorSettings = needOpencorSettings || (solver.name === OPENCOR_SOLVER_NAME);
|
|
471
|
+
|
|
472
|
+
if (solver.version === "") {
|
|
473
|
+
console.warn("JSON: a simulation solver version must not be empty.");
|
|
486
474
|
|
|
487
475
|
return false;
|
|
488
476
|
}
|
|
489
477
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
478
|
+
return true;
|
|
479
|
+
})) {
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
493
482
|
|
|
494
|
-
|
|
495
|
-
|
|
483
|
+
if (needOpencorSettings && (json.simulation.opencor === undefined)) {
|
|
484
|
+
console.warn("JSON: the simulation solver for OpenCOR is specified so simulation OpenCOR settings must also be specified.");
|
|
496
485
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
if (json.simulation.opencor.endingPoint <= 0.0) {
|
|
500
|
-
console.warn("JSON: the simulation OpenCOR ending point (" + json.simulation.opencor.endingPoint + ") must be greater than zero.");
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
501
488
|
|
|
502
|
-
|
|
503
|
-
|
|
489
|
+
if (json.simulation.opencor !== undefined) {
|
|
490
|
+
if (json.simulation.opencor.resource === "") {
|
|
491
|
+
console.warn("JSON: the simulation OpenCOR resource must not be empty.");
|
|
504
492
|
|
|
505
|
-
|
|
506
|
-
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (json.simulation.opencor.endingPoint !== undefined) {
|
|
497
|
+
if (json.simulation.opencor.pointInterval !== undefined) {
|
|
498
|
+
if (json.simulation.opencor.endingPoint <= 0.0) {
|
|
499
|
+
console.warn("JSON: the simulation OpenCOR ending point (" + json.simulation.opencor.endingPoint + ") must be greater than zero.");
|
|
500
|
+
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
507
503
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
} else {
|
|
511
|
-
console.warn("JSON: a simulation OpenCOR ending point is specified so a simulation OpenCOR point interval must also be specified.");
|
|
504
|
+
if (json.simulation.opencor.pointInterval <= 0.0) {
|
|
505
|
+
console.warn("JSON: the simulation OpenCOR point interval (" + json.simulation.opencor.pointInterval + ") must be greater than zero.");
|
|
512
506
|
|
|
513
507
|
return false;
|
|
514
508
|
}
|
|
515
|
-
} else
|
|
516
|
-
console.warn("JSON: a simulation OpenCOR point
|
|
509
|
+
} else {
|
|
510
|
+
console.warn("JSON: a simulation OpenCOR ending point is specified so a simulation OpenCOR point interval must also be specified.");
|
|
517
511
|
|
|
518
512
|
return false;
|
|
519
513
|
}
|
|
514
|
+
} else if (json.simulation.opencor.pointInterval !== undefined) {
|
|
515
|
+
console.warn("JSON: a simulation OpenCOR point interval is specified so a simulation OpenCOR ending point must also be specified.");
|
|
516
|
+
|
|
517
|
+
return false;
|
|
520
518
|
}
|
|
521
519
|
}
|
|
522
520
|
|