myokit 1.33.9__py3-none-any.whl → 1.35.0__py3-none-any.whl
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.
- myokit/__init__.py +9 -36
- myokit/__main__.py +76 -142
- myokit/_aux.py +62 -16
- myokit/_bin/example.mmt +1 -2
- myokit/_bin/install-win/menu.json +7 -7
- myokit/_config.py +22 -31
- myokit/_datablock.py +30 -74
- myokit/_datalog.py +49 -72
- myokit/_err.py +25 -24
- myokit/_expressions.py +50 -68
- myokit/_io.py +15 -27
- myokit/_model_api.py +453 -249
- myokit/_myokit_version.py +1 -5
- myokit/_parsing.py +38 -44
- myokit/_progress.py +5 -8
- myokit/_protocol.py +99 -9
- myokit/_sim/__init__.py +7 -24
- myokit/_sim/cable.c +6 -8
- myokit/_sim/cable.py +6 -8
- myokit/_sim/cmodel.h +125 -70
- myokit/_sim/cmodel.py +12 -14
- myokit/_sim/compiler.py +1 -4
- myokit/_sim/cvodessim.c +196 -118
- myokit/_sim/cvodessim.py +130 -103
- myokit/_sim/differential.hpp +4 -4
- myokit/_sim/fiber_tissue.c +4 -8
- myokit/_sim/fiber_tissue.py +11 -13
- myokit/_sim/jacobian.cpp +2 -2
- myokit/_sim/jacobian.py +11 -8
- myokit/_sim/mcl.h +53 -55
- myokit/_sim/opencl.py +21 -27
- myokit/_sim/openclsim.c +3 -7
- myokit/_sim/openclsim.cl +3 -3
- myokit/_sim/openclsim.py +49 -40
- myokit/_sim/pacing.h +36 -16
- myokit/_sim/rhs.c +6 -13
- myokit/_sim/rhs.py +5 -14
- myokit/_sim/sundials.py +1 -4
- myokit/_system.py +10 -16
- myokit/_unit.py +4 -13
- myokit/float.py +0 -3
- myokit/formats/__init__.py +8 -10
- myokit/formats/ansic/__init__.py +0 -3
- myokit/formats/ansic/_ewriter.py +2 -4
- myokit/formats/ansic/_exporter.py +1 -4
- myokit/formats/ansic/template/cable.c +4 -4
- myokit/formats/ansic/template/euler.c +5 -5
- myokit/formats/ansic/template/sim.c +6 -6
- myokit/formats/axon/__init__.py +1 -3
- myokit/formats/axon/_abf.py +12 -17
- myokit/formats/axon/_atf.py +5 -6
- myokit/formats/axon/_importer.py +0 -3
- myokit/formats/cellml/__init__.py +0 -3
- myokit/formats/cellml/_ewriter.py +3 -6
- myokit/formats/cellml/_exporter.py +3 -6
- myokit/formats/cellml/_importer.py +1 -4
- myokit/formats/cellml/v1/__init__.py +0 -4
- myokit/formats/cellml/v1/_api.py +8 -11
- myokit/formats/cellml/v1/_parser.py +2 -5
- myokit/formats/cellml/v1/_writer.py +2 -11
- myokit/formats/cellml/v2/__init__.py +0 -3
- myokit/formats/cellml/v2/_api.py +8 -17
- myokit/formats/cellml/v2/_parser.py +2 -5
- myokit/formats/cellml/v2/_writer.py +1 -4
- myokit/formats/channelml/__init__.py +0 -3
- myokit/formats/channelml/_importer.py +11 -21
- myokit/formats/cpp/__init__.py +1 -3
- myokit/formats/cpp/_ewriter.py +0 -3
- myokit/formats/cuda/__init__.py +0 -3
- myokit/formats/cuda/_ewriter.py +2 -4
- myokit/formats/cuda/_exporter.py +0 -3
- myokit/formats/cuda/template/kernel.cu +8 -5
- myokit/formats/easyml/__init__.py +0 -3
- myokit/formats/easyml/_ewriter.py +9 -11
- myokit/formats/easyml/_exporter.py +2 -5
- myokit/formats/html/__init__.py +0 -3
- myokit/formats/html/_exporter.py +0 -3
- myokit/formats/html/_flatten.py +5 -21
- myokit/formats/latex/__init__.py +0 -3
- myokit/formats/latex/_ewriter.py +1 -4
- myokit/formats/latex/_exporter.py +4 -6
- myokit/formats/mathml/__init__.py +0 -3
- myokit/formats/mathml/_ewriter.py +2 -11
- myokit/formats/mathml/_parser.py +4 -6
- myokit/formats/matlab/__init__.py +0 -3
- myokit/formats/matlab/_ewriter.py +1 -4
- myokit/formats/matlab/_exporter.py +2 -5
- myokit/formats/matlab/template/main.m +3 -2
- myokit/formats/opencl/__init__.py +0 -3
- myokit/formats/opencl/_ewriter.py +2 -4
- myokit/formats/opencl/_exporter.py +2 -5
- myokit/formats/opencl/template/cable.c +10 -10
- myokit/formats/opencl/template/kernel.cl +1 -1
- myokit/formats/opencl/template/minilog.py +1 -1
- myokit/formats/python/__init__.py +0 -3
- myokit/formats/python/_ewriter.py +2 -5
- myokit/formats/python/_exporter.py +0 -3
- myokit/formats/python/template/sim.py +14 -14
- myokit/formats/sbml/__init__.py +0 -3
- myokit/formats/sbml/_api.py +50 -44
- myokit/formats/sbml/_importer.py +1 -4
- myokit/formats/sbml/_parser.py +2 -5
- myokit/formats/stan/__init__.py +0 -3
- myokit/formats/stan/_ewriter.py +2 -4
- myokit/formats/stan/_exporter.py +2 -5
- myokit/formats/stan/template/cell.stan +3 -3
- myokit/formats/sympy/__init__.py +0 -3
- myokit/formats/sympy/_ereader.py +1 -4
- myokit/formats/sympy/_ewriter.py +2 -5
- myokit/formats/wcp/__init__.py +0 -3
- myokit/formats/wcp/_wcp.py +2 -8
- myokit/formats/xml/__init__.py +0 -3
- myokit/formats/xml/_exporter.py +0 -3
- myokit/formats/xml/_split.py +0 -3
- myokit/gui/__init__.py +80 -246
- myokit/gui/datablock_viewer.py +103 -86
- myokit/gui/datalog_viewer.py +214 -66
- myokit/gui/explorer.py +15 -21
- myokit/gui/ide.py +171 -144
- myokit/gui/progress.py +9 -9
- myokit/gui/source.py +406 -375
- myokit/gui/vargrapher.py +2 -12
- myokit/lib/deps.py +12 -13
- myokit/lib/guess.py +3 -4
- myokit/lib/hh.py +20 -18
- myokit/lib/markov.py +21 -20
- myokit/lib/multi.py +1 -3
- myokit/lib/plots.py +20 -9
- myokit/pacing.py +0 -3
- myokit/pype.py +7 -18
- myokit/tests/__init__.py +3 -6
- myokit/tests/ansic_event_based_pacing.py +1 -4
- myokit/tests/ansic_fixed_form_pacing.py +3 -6
- myokit/tests/data/beeler-1977-model-compare-b.mmt +2 -2
- myokit/tests/data/clancy-1999-fitting.mmt +1 -0
- myokit/tests/test_aux.py +13 -28
- myokit/tests/test_cellml_v1_api.py +4 -19
- myokit/tests/test_cellml_v1_parser.py +0 -15
- myokit/tests/test_cellml_v1_writer.py +0 -9
- myokit/tests/test_cellml_v2_api.py +4 -19
- myokit/tests/test_cellml_v2_parser.py +0 -15
- myokit/tests/test_cellml_v2_writer.py +0 -9
- myokit/tests/test_cmodel.py +16 -22
- myokit/tests/test_compiler_detection.py +1 -11
- myokit/tests/test_component.py +108 -56
- myokit/tests/test_config.py +34 -67
- myokit/tests/test_datablock.py +1 -9
- myokit/tests/test_datalog.py +19 -24
- myokit/tests/test_dependency_checking.py +8 -23
- myokit/tests/test_expressions.py +0 -9
- myokit/tests/test_float.py +1 -5
- myokit/tests/test_formats.py +0 -9
- myokit/tests/test_formats_axon.py +1 -9
- myokit/tests/test_formats_cellml.py +0 -15
- myokit/tests/test_formats_channelml.py +0 -15
- myokit/tests/test_formats_easyml.py +0 -14
- myokit/tests/test_formats_exporters.py +1 -16
- myokit/tests/test_formats_expression_writers.py +1 -17
- myokit/tests/test_formats_html.py +0 -3
- myokit/tests/test_formats_importers.py +1 -16
- myokit/tests/test_formats_mathml_content.py +0 -9
- myokit/tests/test_formats_mathml_presentation.py +0 -9
- myokit/tests/test_formats_opencl.py +0 -10
- myokit/tests/test_formats_sbml.py +0 -15
- myokit/tests/test_formats_sympy.py +0 -9
- myokit/tests/test_formats_wcp.py +1 -3
- myokit/tests/test_io.py +27 -27
- myokit/tests/test_jacobian_calculator.py +6 -14
- myokit/tests/test_jacobian_tracer.py +0 -9
- myokit/tests/test_lib_deps.py +0 -9
- myokit/tests/test_lib_guess.py +0 -9
- myokit/tests/test_lib_hh.py +18 -12
- myokit/tests/test_lib_markov.py +21 -13
- myokit/tests/test_lib_multi.py +0 -9
- myokit/tests/test_lib_plots.py +13 -8
- myokit/tests/test_meta.py +0 -3
- myokit/tests/test_model.py +390 -96
- myokit/tests/test_model_building.py +44 -96
- myokit/tests/test_opencl_info.py +5 -14
- myokit/tests/test_pacing_factory.py +0 -3
- myokit/tests/test_pacing_system_c.py +1 -23
- myokit/tests/test_pacing_system_py.py +0 -9
- myokit/tests/test_parsing.py +139 -56
- myokit/tests/test_progress_reporters.py +0 -3
- myokit/tests/test_protocol.py +0 -9
- myokit/tests/test_protocol_floating_point.py +1 -10
- myokit/tests/test_protocol_time_series.py +82 -0
- myokit/tests/test_pype.py +0 -9
- myokit/tests/test_quantity.py +0 -9
- myokit/tests/test_rhs_benchmarker.py +1 -9
- myokit/tests/test_sbml_api.py +27 -42
- myokit/tests/test_sbml_parser.py +4 -19
- myokit/tests/test_simulation_1d.py +45 -25
- myokit/tests/test_simulation_cvodes.py +321 -55
- myokit/tests/test_simulation_cvodes_from_disk.py +0 -3
- myokit/tests/test_simulation_fiber_tissue.py +39 -12
- myokit/tests/test_simulation_log_interval.py +1 -431
- myokit/tests/test_simulation_opencl.py +69 -48
- myokit/tests/test_simulation_opencl_log_interval.py +1 -3
- myokit/tests/test_simulation_opencl_vs_cvode.py +1 -10
- myokit/tests/test_simulation_opencl_vs_sim1d.py +1 -10
- myokit/tests/test_system_info.py +1 -11
- myokit/tests/test_tools.py +0 -9
- myokit/tests/test_unit.py +1 -10
- myokit/tests/test_user_functions.py +0 -10
- myokit/tests/test_variable.py +231 -27
- myokit/tools.py +5 -21
- myokit/units.py +5 -3
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/METADATA +12 -15
- myokit-1.35.0.dist-info/RECORD +391 -0
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/WHEEL +1 -1
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/entry_points.txt +0 -1
- myokit/_exec_new.py +0 -15
- myokit/_exec_old.py +0 -15
- myokit/_sim/cvodesim.c +0 -1551
- myokit/_sim/cvodesim.py +0 -674
- myokit/_sim/icsim.cpp +0 -563
- myokit/_sim/icsim.py +0 -363
- myokit/_sim/psim.cpp +0 -656
- myokit/_sim/psim.py +0 -493
- myokit/lib/common.py +0 -1094
- myokit/tests/test_lib_common.py +0 -130
- myokit/tests/test_simulation_cvode.py +0 -612
- myokit/tests/test_simulation_ic.py +0 -108
- myokit/tests/test_simulation_p.py +0 -223
- myokit-1.33.9.dist-info/RECORD +0 -403
- /myokit/formats/opencl/template/{test → test.sh} +0 -0
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/LICENSE.txt +0 -0
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/top_level.txt +0 -0
myokit/_sim/mcl.h
CHANGED
|
@@ -67,7 +67,6 @@ static int
|
|
|
67
67
|
mcl_flag2(const char* msg, const cl_int flag)
|
|
68
68
|
{
|
|
69
69
|
char sub[1024];
|
|
70
|
-
char err[2048];
|
|
71
70
|
|
|
72
71
|
if(flag == CL_SUCCESS) {
|
|
73
72
|
return 0;
|
|
@@ -82,164 +81,163 @@ mcl_flag2(const char* msg, const cl_int flag)
|
|
|
82
81
|
switch(flag) {
|
|
83
82
|
// OpenCL 1.0 Errors
|
|
84
83
|
case CL_DEVICE_NOT_FOUND:
|
|
85
|
-
|
|
84
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_DEVICE_NOT_FOUND", sub);
|
|
86
85
|
break;
|
|
87
86
|
case CL_DEVICE_NOT_AVAILABLE:
|
|
88
|
-
|
|
87
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_DEVICE_NOT_AVAILABLE", sub);
|
|
89
88
|
break;
|
|
90
89
|
case CL_COMPILER_NOT_AVAILABLE:
|
|
91
|
-
|
|
90
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_COMPILER_NOT_AVAILABLE", sub);
|
|
92
91
|
break;
|
|
93
92
|
case CL_MEM_OBJECT_ALLOCATION_FAILURE:
|
|
94
|
-
|
|
93
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_MEM_OBJECT_ALLOCATION_FAILURE", sub);
|
|
95
94
|
break;
|
|
96
95
|
case CL_OUT_OF_RESOURCES:
|
|
97
|
-
|
|
96
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_OUT_OF_RESOURCES", sub);
|
|
98
97
|
break;
|
|
99
98
|
case CL_OUT_OF_HOST_MEMORY:
|
|
100
|
-
|
|
99
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_OUT_OF_HOST_MEMORY", sub);
|
|
101
100
|
break;
|
|
102
101
|
case CL_PROFILING_INFO_NOT_AVAILABLE:
|
|
103
|
-
|
|
102
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_PROFILING_INFO_NOT_AVAILABLE", sub);
|
|
104
103
|
break;
|
|
105
104
|
case CL_MEM_COPY_OVERLAP:
|
|
106
|
-
|
|
105
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_MEM_COPY_OVERLAP", sub);
|
|
107
106
|
break;
|
|
108
107
|
case CL_IMAGE_FORMAT_MISMATCH:
|
|
109
|
-
|
|
108
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_IMAGE_FORMAT_MISMATCH", sub);
|
|
110
109
|
break;
|
|
111
110
|
case CL_IMAGE_FORMAT_NOT_SUPPORTED:
|
|
112
|
-
|
|
111
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_IMAGE_FORMAT_NOT_SUPPORTED", sub);
|
|
113
112
|
break;
|
|
114
113
|
case CL_BUILD_PROGRAM_FAILURE:
|
|
115
|
-
|
|
114
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_BUILD_PROGRAM_FAILURE", sub);
|
|
116
115
|
break;
|
|
117
116
|
case CL_MAP_FAILURE:
|
|
118
|
-
|
|
117
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_MAP_FAILURE", sub);
|
|
119
118
|
break;
|
|
120
119
|
case CL_MISALIGNED_SUB_BUFFER_OFFSET:
|
|
121
|
-
|
|
120
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_MISALIGNED_SUB_BUFFER_OFFSET", sub);
|
|
122
121
|
break;
|
|
123
122
|
case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST:
|
|
124
|
-
|
|
123
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST", sub);
|
|
125
124
|
break;
|
|
126
125
|
case CL_INVALID_VALUE:
|
|
127
|
-
|
|
126
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_VALUE", sub);
|
|
128
127
|
break;
|
|
129
128
|
case CL_INVALID_DEVICE_TYPE:
|
|
130
|
-
|
|
129
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_DEVICE_TYPE", sub);
|
|
131
130
|
break;
|
|
132
131
|
case CL_INVALID_PLATFORM:
|
|
133
|
-
|
|
132
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_PLATFORM", sub);
|
|
134
133
|
break;
|
|
135
134
|
case CL_INVALID_DEVICE:
|
|
136
|
-
|
|
135
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_DEVICE", sub);
|
|
137
136
|
break;
|
|
138
137
|
case CL_INVALID_CONTEXT:
|
|
139
|
-
|
|
138
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_CONTEXT", sub);
|
|
140
139
|
break;
|
|
141
140
|
case CL_INVALID_QUEUE_PROPERTIES:
|
|
142
|
-
|
|
141
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_QUEUE_PROPERTIES", sub);
|
|
143
142
|
break;
|
|
144
143
|
case CL_INVALID_COMMAND_QUEUE:
|
|
145
|
-
|
|
144
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_COMMAND_QUEUE", sub);
|
|
146
145
|
break;
|
|
147
146
|
case CL_INVALID_HOST_PTR:
|
|
148
|
-
|
|
147
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_HOST_PTR", sub);
|
|
149
148
|
break;
|
|
150
149
|
case CL_INVALID_MEM_OBJECT:
|
|
151
|
-
|
|
150
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_MEM_OBJECT", sub);
|
|
152
151
|
break;
|
|
153
152
|
case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:
|
|
154
|
-
|
|
153
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_IMAGE_FORMAT_DESCRIPTOR", sub);
|
|
155
154
|
break;
|
|
156
155
|
case CL_INVALID_IMAGE_SIZE:
|
|
157
|
-
|
|
156
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_IMAGE_SIZE", sub);
|
|
158
157
|
break;
|
|
159
158
|
case CL_INVALID_SAMPLER:
|
|
160
|
-
|
|
159
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_SAMPLER", sub);
|
|
161
160
|
break;
|
|
162
161
|
case CL_INVALID_BINARY:
|
|
163
|
-
|
|
162
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_BINARY", sub);
|
|
164
163
|
break;
|
|
165
164
|
case CL_INVALID_BUILD_OPTIONS:
|
|
166
|
-
|
|
165
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_BUILD_OPTIONS", sub);
|
|
167
166
|
break;
|
|
168
167
|
case CL_INVALID_PROGRAM:
|
|
169
|
-
|
|
168
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_PROGRAM", sub);
|
|
170
169
|
break;
|
|
171
170
|
case CL_INVALID_PROGRAM_EXECUTABLE:
|
|
172
|
-
|
|
171
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_PROGRAM_EXECUTABLE", sub);
|
|
173
172
|
break;
|
|
174
173
|
case CL_INVALID_KERNEL_NAME:
|
|
175
|
-
|
|
174
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_KERNEL_NAME", sub);
|
|
176
175
|
break;
|
|
177
176
|
case CL_INVALID_KERNEL_DEFINITION:
|
|
178
|
-
|
|
177
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_KERNEL_DEFINITION", sub);
|
|
179
178
|
break;
|
|
180
179
|
case CL_INVALID_KERNEL:
|
|
181
|
-
|
|
180
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_KERNEL", sub);
|
|
182
181
|
break;
|
|
183
182
|
case CL_INVALID_ARG_INDEX:
|
|
184
|
-
|
|
183
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_ARG_INDEX", sub);
|
|
185
184
|
break;
|
|
186
185
|
case CL_INVALID_ARG_VALUE:
|
|
187
|
-
|
|
186
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_ARG_VALUE", sub);
|
|
188
187
|
break;
|
|
189
188
|
case CL_INVALID_ARG_SIZE:
|
|
190
|
-
|
|
189
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_ARG_SIZE", sub);
|
|
191
190
|
break;
|
|
192
191
|
case CL_INVALID_KERNEL_ARGS:
|
|
193
|
-
|
|
192
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_KERNEL_ARGS", sub);
|
|
194
193
|
break;
|
|
195
194
|
case CL_INVALID_WORK_DIMENSION:
|
|
196
|
-
|
|
195
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_WORK_DIMENSION", sub);
|
|
197
196
|
break;
|
|
198
197
|
case CL_INVALID_WORK_GROUP_SIZE:
|
|
199
|
-
|
|
198
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_WORK_GROUP_SIZE", sub);
|
|
200
199
|
break;
|
|
201
200
|
case CL_INVALID_WORK_ITEM_SIZE:
|
|
202
|
-
|
|
201
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_WORK_ITEM_SIZE", sub);
|
|
203
202
|
break;
|
|
204
203
|
case CL_INVALID_GLOBAL_OFFSET:
|
|
205
|
-
|
|
204
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_GLOBAL_OFFSET", sub);
|
|
206
205
|
break;
|
|
207
206
|
case CL_INVALID_EVENT_WAIT_LIST:
|
|
208
|
-
|
|
207
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_EVENT_WAIT_LIST", sub);
|
|
209
208
|
break;
|
|
210
209
|
case CL_INVALID_EVENT:
|
|
211
|
-
|
|
210
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_EVENT", sub);
|
|
212
211
|
break;
|
|
213
212
|
case CL_INVALID_OPERATION:
|
|
214
|
-
|
|
213
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_OPERATION", sub);
|
|
215
214
|
break;
|
|
216
215
|
case CL_INVALID_GL_OBJECT:
|
|
217
|
-
|
|
216
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_GL_OBJECT", sub);
|
|
218
217
|
break;
|
|
219
218
|
case CL_INVALID_BUFFER_SIZE:
|
|
220
|
-
|
|
219
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_BUFFER_SIZE", sub);
|
|
221
220
|
break;
|
|
222
221
|
case CL_INVALID_MIP_LEVEL:
|
|
223
|
-
|
|
222
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_MIP_LEVEL", sub);
|
|
224
223
|
break;
|
|
225
224
|
case CL_INVALID_GLOBAL_WORK_SIZE:
|
|
226
|
-
|
|
225
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_GLOBAL_WORK_SIZE", sub);
|
|
227
226
|
break;
|
|
228
227
|
case CL_INVALID_PROPERTY:
|
|
229
|
-
|
|
228
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_INVALID_PROPERTY", sub);
|
|
230
229
|
break;
|
|
231
230
|
// OpenCL 1.1 etc. codes can not be assumed to be defined
|
|
232
231
|
// Might be good to have ifdefs or something
|
|
233
232
|
// OpenCL extensions
|
|
234
233
|
case -1001: // CL_PLATFORM_NOT_FOUND_KHR
|
|
235
|
-
|
|
234
|
+
PyErr_Format(PyExc_Exception, "OpenCL error%s: CL_PLATFORM_NOT_FOUND_KHR", sub);
|
|
236
235
|
break;
|
|
237
236
|
// Unknown error
|
|
238
237
|
default:
|
|
239
|
-
|
|
238
|
+
PyErr_Format(PyExc_Exception, "Unknown OpenCL error%s: %i", sub, (int)flag);
|
|
240
239
|
break;
|
|
241
240
|
};
|
|
242
|
-
PyErr_SetString(PyExc_Exception, err);
|
|
243
241
|
return 1;
|
|
244
242
|
}
|
|
245
243
|
|
|
@@ -522,7 +520,7 @@ int mcl_platform_supports_extension(cl_platform_id platform_id, const char* exte
|
|
|
522
520
|
*
|
|
523
521
|
* Arguments:
|
|
524
522
|
* cl_platform_id platform_id The id of the platform to query
|
|
525
|
-
* char* buffer An
|
|
523
|
+
* char* buffer An initialized string buffer, that can be used
|
|
526
524
|
* to read and write string information.
|
|
527
525
|
*
|
|
528
526
|
* Returns NULL and sets an error message if any exception occurs.
|
|
@@ -611,7 +609,7 @@ PyObject* mcl_info_platform_dict(cl_platform_id platform_id, size_t bufsize, cha
|
|
|
611
609
|
* Arguments:
|
|
612
610
|
* cl_device_id device_id The id of the device to query.
|
|
613
611
|
* size_t bufsize Size of the string `buffer`.
|
|
614
|
-
* char* buffer An
|
|
612
|
+
* char* buffer An initialized string buffer, that can be used to
|
|
615
613
|
* read and write string information.
|
|
616
614
|
*
|
|
617
615
|
* Returns NULL and sets an error message if any exception occurs.
|
myokit/_sim/opencl.py
CHANGED
|
@@ -4,24 +4,14 @@
|
|
|
4
4
|
# This file is part of Myokit.
|
|
5
5
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
6
6
|
#
|
|
7
|
-
|
|
8
|
-
from __future__ import print_function, unicode_literals
|
|
9
|
-
|
|
7
|
+
import configparser
|
|
10
8
|
import os
|
|
11
|
-
import myokit
|
|
12
|
-
|
|
13
|
-
try:
|
|
14
|
-
# Python2
|
|
15
|
-
from ConfigParser import ConfigParser
|
|
16
|
-
except ImportError:
|
|
17
|
-
# Python 3
|
|
18
|
-
from configparser import RawConfigParser as ConfigParser
|
|
19
9
|
|
|
10
|
+
import myokit
|
|
20
11
|
|
|
21
12
|
# Settings file
|
|
22
13
|
SETTINGS_FILE = os.path.join(myokit.DIR_USER, 'preferred-opencl-device.ini')
|
|
23
14
|
|
|
24
|
-
|
|
25
15
|
# Location of C source for OpenCL info module
|
|
26
16
|
SOURCE_FILE = 'opencl.c'
|
|
27
17
|
|
|
@@ -41,7 +31,7 @@ class OpenCL(myokit.CModule):
|
|
|
41
31
|
_message = None
|
|
42
32
|
|
|
43
33
|
def __init__(self):
|
|
44
|
-
super(
|
|
34
|
+
super().__init__()
|
|
45
35
|
# Create back-end and cache it
|
|
46
36
|
OpenCL._index += 1
|
|
47
37
|
mname = 'myokit_opencl_info_' + str(OpenCL._index)
|
|
@@ -165,11 +155,8 @@ class OpenCL(myokit.CModule):
|
|
|
165
155
|
# Read ini file
|
|
166
156
|
inifile = os.path.expanduser(SETTINGS_FILE)
|
|
167
157
|
if os.path.isfile(inifile):
|
|
168
|
-
config =
|
|
169
|
-
|
|
170
|
-
config.read(inifile, encoding='ascii') # Python 3
|
|
171
|
-
except TypeError: # pragma: no python 3 cover
|
|
172
|
-
config.read(inifile)
|
|
158
|
+
config = configparser.RawConfigParser()
|
|
159
|
+
config.read(inifile, encoding='ascii')
|
|
173
160
|
|
|
174
161
|
def get(section, option):
|
|
175
162
|
x = None
|
|
@@ -205,7 +192,7 @@ class OpenCL(myokit.CModule):
|
|
|
205
192
|
device = device.encode('ascii').decode('ascii')
|
|
206
193
|
|
|
207
194
|
# Create configuration
|
|
208
|
-
config =
|
|
195
|
+
config = configparser.RawConfigParser()
|
|
209
196
|
config.add_section('selection')
|
|
210
197
|
if platform:
|
|
211
198
|
config.set('selection', 'platform', platform)
|
|
@@ -271,7 +258,7 @@ class OpenCL(myokit.CModule):
|
|
|
271
258
|
'''
|
|
272
259
|
|
|
273
260
|
|
|
274
|
-
class OpenCLInfo
|
|
261
|
+
class OpenCLInfo:
|
|
275
262
|
"""
|
|
276
263
|
Represents information about the available OpenCL platforms and devices.
|
|
277
264
|
|
|
@@ -288,14 +275,18 @@ class OpenCLInfo(object):
|
|
|
288
275
|
"""
|
|
289
276
|
Returns a formatted string version of this object's information.
|
|
290
277
|
"""
|
|
278
|
+
selected_platform, selected_device = myokit.OpenCL.load_selection()
|
|
291
279
|
b = []
|
|
292
280
|
for i, platform in enumerate(self.platforms):
|
|
293
|
-
|
|
294
|
-
platform.
|
|
281
|
+
pname = 'Platform ' + str(i)
|
|
282
|
+
if platform.name == selected_platform: # pragma: no cover
|
|
283
|
+
pname += ' <-- Selected platform in myokit.ini'
|
|
284
|
+
b.append(pname)
|
|
285
|
+
platform._format(b, selected_platform, selected_device, pre=' ')
|
|
295
286
|
return '\n'.join(b)
|
|
296
287
|
|
|
297
288
|
|
|
298
|
-
class OpenCLPlatformInfo
|
|
289
|
+
class OpenCLPlatformInfo:
|
|
299
290
|
"""
|
|
300
291
|
Represents information about an OpenCL platform.
|
|
301
292
|
|
|
@@ -342,10 +333,10 @@ class OpenCLPlatformInfo(object):
|
|
|
342
333
|
"""
|
|
343
334
|
b = []
|
|
344
335
|
b.append('Platform: ' + self.name)
|
|
345
|
-
self._format(b, ' ', name=False)
|
|
336
|
+
self._format(b, pre=' ', name=False)
|
|
346
337
|
return '\n'.join(b)
|
|
347
338
|
|
|
348
|
-
def _format(self, b, pre='', name=True):
|
|
339
|
+
def _format(self, b, p_selected=None, d_selected=None, pre='', name=True):
|
|
349
340
|
"""
|
|
350
341
|
Formats the information in this object and adds it to the list ``b``.
|
|
351
342
|
"""
|
|
@@ -358,7 +349,10 @@ class OpenCLPlatformInfo(object):
|
|
|
358
349
|
if self.devices is not None:
|
|
359
350
|
b.append(pre + 'Devices:')
|
|
360
351
|
for j, device in enumerate(self.devices):
|
|
361
|
-
|
|
352
|
+
dname = pre + ' Device ' + str(j)
|
|
353
|
+
if self.name == p_selected and device.name == d_selected: # pragma: no cover # noqa
|
|
354
|
+
dname += ' <-- Selected device in myokit.ini'
|
|
355
|
+
b.append(dname)
|
|
362
356
|
device._format(b, pre + ' ')
|
|
363
357
|
|
|
364
358
|
if self.device is not None:
|
|
@@ -369,7 +363,7 @@ class OpenCLPlatformInfo(object):
|
|
|
369
363
|
return extension in self.extensions
|
|
370
364
|
|
|
371
365
|
|
|
372
|
-
class OpenCLDeviceInfo
|
|
366
|
+
class OpenCLDeviceInfo:
|
|
373
367
|
"""
|
|
374
368
|
Represents information about an OpenCL device.
|
|
375
369
|
|
myokit/_sim/openclsim.c
CHANGED
|
@@ -515,9 +515,7 @@ sim_init(PyObject* self, PyObject* args)
|
|
|
515
515
|
for(i=0; i<nx * ny * n_state; i++) {
|
|
516
516
|
flt = PyList_GetItem(state_in, (Py_ssize_t)i); // Don't decref!
|
|
517
517
|
if(!PyFloat_Check(flt)) {
|
|
518
|
-
|
|
519
|
-
sprintf(errstr, "Item %u in state vector is not a float.", (unsigned int)i);
|
|
520
|
-
PyErr_SetString(PyExc_Exception, errstr);
|
|
518
|
+
PyErr_Format(PyExc_Exception, "Item %u in state vector is not a float.", (unsigned int)i);
|
|
521
519
|
return sim_clean();
|
|
522
520
|
}
|
|
523
521
|
rvec_state[i] = (Real)PyFloat_AsDouble(flt);
|
|
@@ -552,9 +550,7 @@ sim_init(PyObject* self, PyObject* args)
|
|
|
552
550
|
for(i=0; i<n_field_data; i++) {
|
|
553
551
|
flt = PyList_GetItem(field_data, (Py_ssize_t)i); // No need to decref
|
|
554
552
|
if(!PyFloat_Check(flt)) {
|
|
555
|
-
|
|
556
|
-
sprintf(errstr, "Item %u in field data is not a float.", (unsigned int)i);
|
|
557
|
-
PyErr_SetString(PyExc_Exception, errstr);
|
|
553
|
+
PyErr_Format(PyExc_Exception, "Item %u in field data is not a float.", (unsigned int)i);
|
|
558
554
|
return sim_clean();
|
|
559
555
|
}
|
|
560
556
|
rvec_field_data[i] = (Real)PyFloat_AsDouble(flt);
|
|
@@ -975,7 +971,7 @@ for var in model.states():
|
|
|
975
971
|
print(3*tab + 'sprintf(log_var_name, "%u.' + var.qname() + '", (unsigned int)j);')
|
|
976
972
|
else:
|
|
977
973
|
print(3*tab + 'sprintf(log_var_name, "%u.%u.' + var.qname() + '", (unsigned int)j, (unsigned int)i);' )
|
|
978
|
-
print(3*tab + 'if(log_add(log_dict, logs, vars, k_vars, log_var_name, &rvec_state[(i*nx+j)*n_state+' + str(var.
|
|
974
|
+
print(3*tab + 'if(log_add(log_dict, logs, vars, k_vars, log_var_name, &rvec_state[(i*nx+j)*n_state+' + str(var.index()) + '])) {')
|
|
979
975
|
print(4*tab + 'logging_states = 1;')
|
|
980
976
|
print(4*tab + 'k_vars++;')
|
|
981
977
|
print(3*tab + '}')
|
myokit/_sim/openclsim.cl
CHANGED
|
@@ -152,8 +152,8 @@ if precision == myokit.DOUBLE_PRECISION:
|
|
|
152
152
|
|
|
153
153
|
<?
|
|
154
154
|
if diffusion:
|
|
155
|
-
print('/*
|
|
156
|
-
print('#define i_vm ' + str(model.label('membrane_potential').
|
|
155
|
+
print('/* Index of membrane potential in state vector */')
|
|
156
|
+
print('#define i_vm ' + str(model.label('membrane_potential').index()))
|
|
157
157
|
|
|
158
158
|
if precision == myokit.SINGLE_PRECISION:
|
|
159
159
|
print('/* Using single precision floats */')
|
|
@@ -188,7 +188,7 @@ for group in equations.values():
|
|
|
188
188
|
print('')
|
|
189
189
|
print('/* Aliases of state variables. */')
|
|
190
190
|
for var in model.states():
|
|
191
|
-
print('#define ' + v(var) + ' state[of1 + ' + str(var.
|
|
191
|
+
print('#define ' + v(var) + ' state[of1 + ' + str(var.index()) + ']')
|
|
192
192
|
|
|
193
193
|
print('')
|
|
194
194
|
print('/* Aliases of logged intermediary variables. */')
|
myokit/_sim/openclsim.py
CHANGED
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
# This file is part of Myokit.
|
|
6
6
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
7
7
|
#
|
|
8
|
-
from __future__ import absolute_import, division
|
|
9
|
-
from __future__ import print_function, unicode_literals
|
|
10
|
-
|
|
11
8
|
import os
|
|
12
|
-
import myokit
|
|
13
|
-
import numpy as np
|
|
14
9
|
import platform
|
|
10
|
+
|
|
15
11
|
from collections import OrderedDict
|
|
16
12
|
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
import myokit
|
|
16
|
+
|
|
17
17
|
|
|
18
18
|
# Location of C and OpenCL sources
|
|
19
19
|
SOURCE_FILE = 'openclsim.c'
|
|
@@ -58,7 +58,7 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
58
58
|
``pace``
|
|
59
59
|
The pacing level, this is set if a protocol was passed in.
|
|
60
60
|
``diffusion_current`` (if enabled)
|
|
61
|
-
The current flowing from the cell to its
|
|
61
|
+
The current flowing from the cell to its neighbors. This will be
|
|
62
62
|
positive when the cell is acting as a source, negative when it is
|
|
63
63
|
acting as a sink.
|
|
64
64
|
|
|
@@ -103,7 +103,7 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
103
103
|
cells ``i - 1`` and ``i + 1`` (except at the boundaries).
|
|
104
104
|
Similarly, if ``ncells`` is a 2-dimensional tuple ``(nx, ny)`` a grid will
|
|
105
105
|
be assumed so that each (non-boundary) cell is connected to four
|
|
106
|
-
|
|
106
|
+
neighbors.
|
|
107
107
|
Finally, arbitrary geometries can be used by passing a scalar to ``ncells``
|
|
108
108
|
and specifying the connections with :meth:`set_connections`.
|
|
109
109
|
|
|
@@ -148,7 +148,7 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
148
148
|
def __init__(
|
|
149
149
|
self, model, protocol=None, ncells=256, diffusion=True,
|
|
150
150
|
precision=myokit.SINGLE_PRECISION, native_maths=False, rl=False):
|
|
151
|
-
super(
|
|
151
|
+
super().__init__()
|
|
152
152
|
|
|
153
153
|
# Require a valid model
|
|
154
154
|
if not model.is_valid():
|
|
@@ -272,7 +272,7 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
272
272
|
self._nstate = self._model.count_states()
|
|
273
273
|
|
|
274
274
|
# Set state and default state
|
|
275
|
-
self._state = self._model.
|
|
275
|
+
self._state = self._model.initial_values(True) * self._ntotal
|
|
276
276
|
self._default_state = list(self._state)
|
|
277
277
|
|
|
278
278
|
# List of globally logged inputs
|
|
@@ -283,7 +283,7 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
283
283
|
inputs = {'time': 'time', 'pace': 'pace'}
|
|
284
284
|
if self._diffusion_enabled:
|
|
285
285
|
inputs['diffusion_current'] = 'idiff'
|
|
286
|
-
self._bound_variables = self._model
|
|
286
|
+
self._bound_variables = myokit._prepare_bindings(self._model, inputs)
|
|
287
287
|
|
|
288
288
|
# Create unique names
|
|
289
289
|
self._model.create_unique_names()
|
|
@@ -657,7 +657,7 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
657
657
|
|
|
658
658
|
# Get value causing error
|
|
659
659
|
if var.is_state():
|
|
660
|
-
value = states[1 if ifirst > 0 else 0][var.
|
|
660
|
+
value = states[1 if ifirst > 0 else 0][var.index()]
|
|
661
661
|
else: # pragma: no cover
|
|
662
662
|
value = bounds[1 if ifirst > 0 else 0][var.qname()]
|
|
663
663
|
var = var.qname()
|
|
@@ -765,9 +765,9 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
765
765
|
|
|
766
766
|
I_diff[i] = sum[g[i,j] * (V[i] - V[j])]
|
|
767
767
|
|
|
768
|
-
in which the sum is over all
|
|
768
|
+
in which the sum is over all neighbors ``j`` of cell ``i``.
|
|
769
769
|
|
|
770
|
-
Alternatively, with capacitance and currents
|
|
770
|
+
Alternatively, with capacitance and currents normalized to membrane
|
|
771
771
|
area, we can write::
|
|
772
772
|
|
|
773
773
|
dV/dt = -1/cm (i_ion + i_stim + i_diff)
|
|
@@ -787,10 +787,10 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
787
787
|
|
|
788
788
|
g_bar = (1 / chi) * (k / (k + 1)) * D * (1 / dx^2)
|
|
789
789
|
|
|
790
|
-
where ``g_bar`` is the cell-to-cell conductance, but
|
|
790
|
+
where ``g_bar`` is the cell-to-cell conductance, but normalized with
|
|
791
791
|
respect to unit membrane area.
|
|
792
|
-
For models with currents
|
|
793
|
-
to convert to models with
|
|
792
|
+
For models with currents normalized to area this is unproblematic, but
|
|
793
|
+
to convert to models with unnormalized currents this means we have
|
|
794
794
|
added the further assumption that **each node contains some fixed
|
|
795
795
|
amount of membrane**, determined by an area A::
|
|
796
796
|
|
|
@@ -825,9 +825,9 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
825
825
|
"""
|
|
826
826
|
return D * A * k / ((k + 1) * chi * dx * dx)
|
|
827
827
|
|
|
828
|
-
def
|
|
828
|
+
def neighbors(self, x, y=None):
|
|
829
829
|
"""
|
|
830
|
-
Returns a list of indices specifying the
|
|
830
|
+
Returns a list of indices specifying the neighbors of the cell at
|
|
831
831
|
index ``x`` (or index ``(x, y)`` for 2d simulations).
|
|
832
832
|
|
|
833
833
|
Indices are given either as integers (1d or arbitrary geometry) or as
|
|
@@ -857,29 +857,38 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
857
857
|
|
|
858
858
|
# User-specified connections (always 1d)
|
|
859
859
|
if self._connections is not None:
|
|
860
|
-
|
|
860
|
+
neighbors = []
|
|
861
861
|
for i, j, c in self._connections:
|
|
862
862
|
if i == x:
|
|
863
|
-
|
|
863
|
+
neighbors.append(j)
|
|
864
864
|
elif j == x:
|
|
865
|
-
|
|
866
|
-
return
|
|
865
|
+
neighbors.append(i)
|
|
866
|
+
return neighbors
|
|
867
867
|
|
|
868
|
-
# Left and right
|
|
869
|
-
|
|
868
|
+
# Left and right neighbors
|
|
869
|
+
neighbors = []
|
|
870
870
|
if x > 0:
|
|
871
|
-
|
|
871
|
+
neighbors.append(x - 1)
|
|
872
872
|
if x + 1 < self._dims[0]:
|
|
873
|
-
|
|
873
|
+
neighbors.append(x + 1)
|
|
874
874
|
|
|
875
|
-
# Top and bottom
|
|
875
|
+
# Top and bottom neighbors
|
|
876
876
|
if len(self._dims) == 2:
|
|
877
|
-
|
|
877
|
+
neighbors = [(i, y) for i in neighbors]
|
|
878
878
|
if y > 0:
|
|
879
|
-
|
|
879
|
+
neighbors.append((x, y - 1))
|
|
880
880
|
if y + 1 < self._dims[1]:
|
|
881
|
-
|
|
882
|
-
return
|
|
881
|
+
neighbors.append((x, y + 1))
|
|
882
|
+
return neighbors
|
|
883
|
+
|
|
884
|
+
def neighbours(self, x, y=None):
|
|
885
|
+
""" Alias of :meth:`neighbors`. """
|
|
886
|
+
# Deprecated since 2023-06-07
|
|
887
|
+
import warnings
|
|
888
|
+
warnings.warn('The method SimulationOpenCL.neighbours() is deprecated.'
|
|
889
|
+
' Please use neighbors() instead.')
|
|
890
|
+
|
|
891
|
+
return self.neighbors(x, y)
|
|
883
892
|
|
|
884
893
|
def pre(self, duration, report_nan=True, progress=None,
|
|
885
894
|
msg='Pre-pacing SimulationOpenCL'):
|
|
@@ -1165,14 +1174,14 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
1165
1174
|
vdiff = self._model.binding('diffusion_current')
|
|
1166
1175
|
vdiff = None if vdiff is None else vdiff.qname()
|
|
1167
1176
|
|
|
1168
|
-
# List all
|
|
1169
|
-
|
|
1177
|
+
# List all neighbors for this cell
|
|
1178
|
+
neighbors = self.neighbors(*icell)
|
|
1170
1179
|
if len(self._dims) == 2:
|
|
1171
|
-
|
|
1180
|
+
neighbors_str = ', '.join(
|
|
1172
1181
|
('(' + ','.join([str(i) for i in j]) + ')')
|
|
1173
|
-
for j in
|
|
1182
|
+
for j in neighbors)
|
|
1174
1183
|
else:
|
|
1175
|
-
|
|
1184
|
+
neighbors_str = ', '.join(str(j) for j in neighbors)
|
|
1176
1185
|
|
|
1177
1186
|
# Show final state
|
|
1178
1187
|
txt.append('State during:')
|
|
@@ -1192,8 +1201,8 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
1192
1201
|
txt.append(
|
|
1193
1202
|
' Diffusion current: ' + myokit.float.str(
|
|
1194
1203
|
bounds[0][vdiff], precision=self._precision))
|
|
1195
|
-
if
|
|
1196
|
-
txt.append(' Connected cells: ' +
|
|
1204
|
+
if neighbors:
|
|
1205
|
+
txt.append(' Connected cells: ' + neighbors_str)
|
|
1197
1206
|
|
|
1198
1207
|
# Show previous state (and derivatives)
|
|
1199
1208
|
n_states = len(states)
|
|
@@ -1239,8 +1248,8 @@ class SimulationOpenCL(myokit.CModule):
|
|
|
1239
1248
|
txt.append(
|
|
1240
1249
|
' Diffusion current: ' + myokit.float.str(
|
|
1241
1250
|
bounds[1][vdiff], precision=self._precision))
|
|
1242
|
-
if
|
|
1243
|
-
txt.append(' Connected cells: ' +
|
|
1251
|
+
if neighbors:
|
|
1252
|
+
txt.append(' Connected cells: ' + neighbors_str)
|
|
1244
1253
|
|
|
1245
1254
|
# Show all variables with non-finite values
|
|
1246
1255
|
txt.append(
|