Vensim Tips and Tricks

Debugging a model

A common occurring problem is that some of the runs of a Vensim model do not complete correctly. In the logger, we see a message stating that a run did not complete correct, with a description of the case that did not complete correctly attached to it. Typically, this error is due to a division by zero somewhere in the model during the simulation. The easiest way of finding the source of the division by zero is via Vensim itself. However, this requires that the model is parameterized as specified by the case that created the error. It is of course possible to set all the parameters by hand, however this becomes annoying on larger models, or if one has to do it multiple times. Since the Vensim DLL does not have a way to save a model, we cannot use the DLL. Instead, we can use the fact that one can save a Vensim model as a text file. By changing the required parameters in this text file via the workbench, we can then open the modified model in Vensim and spot the error.

The following script can be used for this purpose.

 1"""
 2Created on 11 aug. 2011
 3
 4.. codeauthor:: wauping <w.auping (at) student (dot) tudelft (dot) nl>
 5                jhkwakkel <j.h.kwakkel (at) tudelft (dot) nl>
 6
 7
 8To be able to debug the Vensim model, a few steps are needed:
 9
10    1.  The case that gave a bug, needs to be saved in a text  file. The entire
11        case description should be on a single line.
12    2.  Reform and clean your model ( In the Vensim menu: Model, Reform and
13        Clean). Choose
14
15         * Equation Order: Alphabetical by group (not really necessary)
16         * Equation Format: Terse
17
18    3.  Save your model as text (File, Save as..., Save as Type: Text Format
19        Models
20    4.  Run this script
21    5.  If the print in the end is not set([]), but set([array]), the array
22        gives the values that where not found and changed
23    5.  Run your new model (for example 'new text.mdl')
24    6.  Vensim tells you about your critical mistake
25
26"""
27
28fileSpecifyingError = ""
29
30pathToExistingModel = "/salinization/Verzilting_aanpassingen incorrect.mdl"
31pathToNewModel = "/models/salinization/Verzilting_aanpassingen correct.mdl"
32newModel = open(pathToNewModel, "w")
33
34# line = open(fileSpecifyingError).read()
35
36line = "rainfall : 0.154705633188; adaptation time from non irrigated agriculture : 0.915157119079; salt effect multiplier : 1.11965969891; adaptation time to non irrigated agriculture : 0.48434342934; adaptation time to irrigated agriculture : 0.330990830832; water shortage multiplier : 0.984356102036; delay time salt seepage : 6.0; adaptation time : 6.90258192256; births multiplier : 1.14344734715; diffusion lookup : [(0, 8.0), (10, 8.0), (20, 8.0), (30, 8.0), (40, 7.9999999999999005), (50, 4.0), (60, 9.982194802803703e-14), (70, 1.2455526635140464e-27), (80, 1.5541686655435471e-41), (90, 1.9392517969836692e-55)]; salinity effect multiplier : 1.10500381093; technological developments in irrigation : 0.0117979353255; adaptation time from irrigated agriculture : 1.58060947607; food shortage multiplier : 0.955325345996; deaths multiplier : 0.875605669911; "
37
38# we assume the case specification was copied from the logger
39splitOne = line.split(",")
40variable = {}
41for n in range(len(splitOne) - 1):
42    splitTwo = splitOne[n].split(":")
43    variableElement = splitTwo[0]
44    # Delete the spaces and other rubish on the sides of the variable name
45    variableElement = variableElement.lstrip()
46    variableElement = variableElement.lstrip("'")
47    variableElement = variableElement.rstrip()
48    variableElement = variableElement.rstrip("'")
49    print(variableElement)
50    valueElement = splitTwo[1]
51    valueElement = valueElement.lstrip()
52    valueElement = valueElement.rstrip()
53    variable[variableElement] = valueElement
54print(variable)
55
56# This generates a new (text-formatted) model
57changeNextLine = False
58settedValues = []
59for line in open(pathToExistingModel):
60    if line.find("=") != -1:
61        elements = line.split("=")
62        value = elements[0]
63        value = value.strip()
64        if value in variable:
65            elements[1] = variable.get(value)
66            line = elements[0] + " = " + elements[1]
67            settedValues.append(value)
68
69    newModel.write(line)
70newModel.close()  # in order to be able to open the model in Vensim
71notSet = set(variable.keys()) - set(settedValues)
72print(notSet)