1 /* Steven Andrews, started 10/22/2001.
2 This is an application programming interface for the Smoldyn program.
3 See documentation called SmoldynManual.pdf and SmoldynCodeDoc.pdf, and the Smoldyn
4 website, which is at www.smoldyn.org.
5 Copyright 2003-2016 by Steven Andrews. This work is distributed under the terms
6 of the Gnu Lesser General Public License (LGPL). */
7
8 #include <string.h>
9 #include "../libSteve/List.h"
10 #include "opengl2.h"
11 #include "SimCommand.h"
12 #include "string2.h"
13 #include "List.h"
14
15 #include "smoldyn.h"
16 #include "smoldynfuncs.h"
17 #include "libsmoldyn.h"
18 #ifdef OPTION_VCELL
19 #include "SimpleValueProvider.h"
20 #include "SimpleMesh.h"
21 #endif
22
23 #define LCHECK(A,B,C,D) if(!(A)) {smolSetError(B,C,D,sim?sim->flags:"");if(C<ECwarning) goto failure;} else (void)0
24 #define LCHECKNT(A,B,C,D) if(!(A)) {smolSetErrorNT(B,C,D);if(C<ECwarning) goto failure;} else (void)0
25
26 #ifdef __cplusplus
27 #define CSTRING "C"
28 #else
29 #define CSTRING
30 #endif
31
32
33 enum ErrorCode Liberrorcode=ECok;
34 enum ErrorCode Libwarncode=ECok;
35 char Liberrorfunction[STRCHAR]="";
36 char Liberrorstring[STRCHAR]="";
37 int Libdebugmode=1;
38 int LibThrowThreshold=11;
39
40 PanelShape AllPanels_arr[6] = {PanelShape::PSrect, PanelShape::PStri,
41 PanelShape::PSsph, PanelShape::PScyl, PanelShape::PShemi, PanelShape::PSdisk};
42
43
44 /******************************************************************************/
45 /******************************* Miscellaneous ********************************/
46 /******************************************************************************/
47
48
49 /* smolGetVersion */
smolGetVersion(void)50 extern CSTRING double smolGetVersion(void) {
51 return simversionnumber(); }
52
53
54 /******************************************************************************/
55 /*********************************** Errors ***********************************/
56 /******************************************************************************/
57
58 /* smolSetLogging */
smolSetLogging(FILE * logfile,void (* logFunction)(simptr,int,const char *,...))59 extern CSTRING void smolSetLogging(FILE *logfile,void (*logFunction)(simptr,int,const char*,...)) {
60 simSetLogging(logfile,logFunction);
61 return; }
62
63
64 /* smolSetThrowing */
smolSetThrowing(int corethreshold,int libthreshold)65 extern CSTRING void smolSetThrowing(int corethreshold,int libthreshold) {
66 simSetThrowing(corethreshold);
67 LibThrowThreshold=libthreshold;
68 return; }
69
70
71 /* smolSetError */
smolSetError(const char * errorfunction,enum ErrorCode errorcode,const char * errorstring,const char * flags)72 extern CSTRING void smolSetError(const char *errorfunction,enum ErrorCode errorcode,const char *errorstring,const char *flags) {
73 char string[STRCHAR];
74 int qflag,sflag,wflag;
75 // int severity;
76
77 if(flags) {
78 qflag=strchr(flags,'q')?1:0;
79 sflag=strchr(flags,'s')?1:0;
80 wflag=strchr(flags,'w')?1:0; }
81 else {
82 qflag=sflag=wflag=0; }
83
84 if(errorcode!=ECsame) {
85 Liberrorcode=errorcode;
86 Libwarncode=(errorcode>=ECwarning)?errorcode:ECok;
87 if(errorstring)
88 strncpy(Liberrorstring,errorstring,STRCHAR-1);
89 else Liberrorstring[0]='\0'; }
90 if(errorfunction)
91 strncpy(Liberrorfunction,errorfunction,STRCHAR-1);
92 else Liberrorfunction[0]='\0';
93
94 // severity=-(int)errorcode;
95 //?? if(LibThrowThreshold<severity) throw; //?? This is disabled for now because I can't link libsmoldyn statically if not
96
97 if(Libdebugmode && Liberrorfunction[0]!='\0') {
98 if(Liberrorcode==ECnotify) {
99 if(!qflag && !sflag)
100 fprintf(stderr,"Libsmoldyn notification from %s: %s\n",Liberrorfunction,Liberrorstring); }
101 else if(Liberrorcode==ECwarning) {
102 if(!sflag && !wflag)
103 fprintf(stderr,"Libsmoldyn warning in %s: %s\n",Liberrorfunction,Liberrorstring); }
104 else {
105 if(!sflag)
106 fprintf(stderr,"Libsmoldyn '%s' error in %s: %s\n",smolErrorCodeToString(Liberrorcode,string),Liberrorfunction,Liberrorstring); }}
107 return; }
108
109
110 /* smolSetErrorNT */
smolSetErrorNT(const char * errorfunction,enum ErrorCode errorcode,const char * errorstring)111 extern CSTRING void smolSetErrorNT(const char *errorfunction,enum ErrorCode errorcode,const char *errorstring) {
112 if(errorcode!=ECsame) {
113 Liberrorcode=errorcode;
114 Libwarncode=(errorcode>=ECwarning)?errorcode:ECok;
115 if(errorstring) {
116 strncpy(Liberrorstring,errorstring,STRCHAR-1);
117 Liberrorstring[STRCHAR-1] = '\0'; }
118 else Liberrorstring[0]='\0'; }
119 if(errorfunction)
120 strncpy(Liberrorfunction,errorfunction,STRCHAR-1);
121 else Liberrorfunction[0]='\0';
122 return; }
123
124
125 /* smolGetError */
smolGetError(char * errorfunction,char * errorstring,int clearerror)126 extern CSTRING enum ErrorCode smolGetError(char *errorfunction,char *errorstring,int clearerror) {
127 enum ErrorCode erc;
128
129 erc=Liberrorcode;
130 if(errorfunction) strcpy(errorfunction,Liberrorfunction);
131 if(errorstring) strcpy(errorstring,Liberrorstring);
132 if(clearerror) smolClearError();
133 return erc; }
134
135
136 /* smolClearError */
smolClearError(void)137 extern CSTRING void smolClearError(void) {
138 Liberrorcode=ECok;
139 Libwarncode=ECok;
140 Liberrorfunction[0]='\0';
141 Liberrorstring[0]='\0';
142 return; }
143
144
145 /* smolSetDebugMode */
smolSetDebugMode(int debugmode)146 extern CSTRING void smolSetDebugMode(int debugmode) {
147 Libdebugmode=debugmode;
148 return; }
149
150
151 /* smolErrorCodeToString */
smolErrorCodeToString(enum ErrorCode erc,char * string)152 extern CSTRING char *smolErrorCodeToString(enum ErrorCode erc,char *string) {
153 if(erc==ECok) strcpy(string,"ok");
154 else if(erc==ECnotify) strcpy(string,"notify");
155 else if(erc==ECwarning) strcpy(string,"warning");
156 else if(erc==ECnonexist) strcpy(string,"nonexistant");
157 else if(erc==ECall) strcpy(string,"all");
158 else if(erc==ECmissing) strcpy(string,"missing");
159 else if(erc==ECbounds) strcpy(string,"bounds");
160 else if(erc==ECsyntax) strcpy(string,"syntax");
161 else if(erc==ECerror) strcpy(string,"error");
162 else if(erc==ECmemory) strcpy(string,"memory");
163 else if(erc==ECbug) strcpy(string,"Smoldyn bug");
164 else if(erc==ECsame) strcpy(string,"same as before");
165 else strcpy(string,"undefined");
166 return string; }
167
168
169 /******************************************************************************/
170 /******************************** Sim structure *******************************/
171 /******************************************************************************/
172
173 /* smolNewSim */
smolNewSim(int dim,double * lowbounds,double * highbounds)174 extern CSTRING simptr smolNewSim(int dim,double *lowbounds,double *highbounds) {
175 const char *funcname="smolNewSim";
176 simptr sim;
177 int d,er;
178
179 sim=NULL;
180 LCHECK(dim>0,funcname,ECbounds,"dim must be >0");
181 LCHECK(dim<=3,funcname,ECbounds,"dim must be <=3");
182 LCHECK(lowbounds,funcname,ECmissing,"missing lowbounds");
183 LCHECK(highbounds,funcname,ECmissing,"missing highbounds");
184 for(d=0;d<dim;d++)
185 LCHECK(lowbounds[d]<highbounds[d],funcname,ECbounds,"lowbounds must be < highbounds");
186
187 sim=simalloc(NULL);
188 LCHECK(sim,funcname,ECmemory,"allocating sim");
189 er=simsetdim(sim,dim);
190 LCHECK(!er,funcname,ECbug,"simsetdim bug");
191 for(d=0;d<dim;d++) {
192 er=walladd(sim,d,0,lowbounds[d],'t');
193 LCHECK(!er,funcname,ECmemory,"allocating wall");
194 er=walladd(sim,d,1,highbounds[d],'t');
195 LCHECK(!er,funcname,ECmemory,"allocating wall"); }
196
197 return sim;
198 failure:
199 if(sim) simfree(sim);
200 return NULL; }
201
202
203 /* smolUpdateSim */
smolUpdateSim(simptr sim)204 extern CSTRING enum ErrorCode smolUpdateSim(simptr sim) {
205 const char *funcname="smolUpdateSim";
206 int er;
207
208 LCHECK(sim,funcname,ECmissing,"missing sim");
209 er=simupdate(sim);
210 LCHECK(!er,funcname,ECerror,ErrorString); //?? check error handling
211 return ECok;
212 failure:
213 return Liberrorcode; }
214
215
216 /* smolRunTimeStep */
smolRunTimeStep(simptr sim)217 extern CSTRING enum ErrorCode smolRunTimeStep(simptr sim) {
218 const char *funcname="smolRunTimeStep";
219 int er;
220
221 LCHECK(sim,funcname,ECmissing,"missing sim");
222 simsettime(sim,sim->time+sim->dt/2,4);
223 er=smolsimulate(sim);
224 LCHECK(er!=1,funcname,ECnotify,"Simulation complete");
225 LCHECK(er!=2,funcname,ECerror,"Simulation terminated during molecule assignment\n Out of memory");
226 LCHECK(er!=3,funcname,ECerror,"Simulation terminated during order 0 reaction\n");
227 LCHECK(er!=4,funcname,ECerror,"Simulation terminated during order 1 reaction\n");
228 LCHECK(er!=5,funcname,ECerror,"Simulation terminated during order 2 reaction\n");
229 LCHECK(er!=6,funcname,ECerror,"Simulation terminated during molecule sorting\n Out of memory");
230 LCHECK(er!=7,funcname,ECnotify,"Simulation stopped by a runtime command");
231 LCHECK(er!=8,funcname,ECerror,"Simulation terminated during simulation state updating\n Out of memory");
232 LCHECK(er!=9,funcname,ECerror,"Simulation terminated during diffusion\n Out of memory");
233 LCHECK(er!=11,funcname,ECerror,"Simulation terminated during filament dynamics");
234 LCHECK(er!=12,funcname,ECerror,"Simulation terminated during lattice simulation");
235 LCHECK(er!=13,funcname,ECerror,"Simulation terminated during reaction network expansion");
236 return Libwarncode;
237 failure:
238 return Liberrorcode; }
239
240
241 /* smolRunSim */
smolRunSim(simptr sim)242 extern CSTRING enum ErrorCode smolRunSim(simptr sim) {
243 const char *funcname="smolRunSim";
244 int er;
245
246 LCHECK(sim,funcname,ECmissing,"missing sim");
247 er=smolOpenOutputFiles(sim, true);
248 LCHECK(!er,funcname,ECerror,"Cannot open output files for writing");
249
250 if(sim->graphss && sim->graphss->graphics>0 && !strchr(sim->flags,'t'))
251 smolsimulategl(sim);
252 else {
253 er=smolsimulate(sim);
254 LCHECK(er!=1,funcname,ECnotify,"Simulation complete");
255 LCHECK(er!=2,funcname,ECerror,"Simulation terminated during molecule assignment\n Out of memory");
256 LCHECK(er!=3,funcname,ECerror,"Simulation terminated during order 0 reaction\n Not enough molecules allocated");
257 LCHECK(er!=4,funcname,ECerror,"Simulation terminated during order 1 reaction\n Not enough molecules allocated");
258 LCHECK(er!=5,funcname,ECerror,"Simulation terminated during order 2 reaction\n Not enough molecules allocated");
259 LCHECK(er!=6,funcname,ECerror,"Simulation terminated during molecule sorting\n Out of memory");
260 LCHECK(er!=7,funcname,ECnotify,"Simulation stopped by a runtime command");
261 LCHECK(er!=8,funcname,ECerror,"Simulation terminated during simulation state updating\n Out of memory");
262 LCHECK(er!=9,funcname,ECerror,"Simulation terminated during diffusion\n Out of memory"); }
263
264 // FIXME. If run() is called again, previous Liberrorcode does not
265 // reset to ECok but remain stuck to ECnotify.
266 if(Libwarncode == ECnotify)
267 Libwarncode = ECok;
268 return Libwarncode;
269 failure:
270 return Liberrorcode; }
271
272
273 /* smolRunSimUntil */
smolRunSimUntil(simptr sim,double breaktime)274 extern CSTRING enum ErrorCode smolRunSimUntil(simptr sim,double breaktime) {
275 const char *funcname="smolRunSimUntil";
276 double stoptime;
277
278 LCHECK(sim,funcname,ECmissing,"missing sim");
279 stoptime=sim->tmax;
280 simsettime(sim,breaktime,4);
281 smolRunSim(sim);
282 simsettime(sim,stoptime,4);
283 return Libwarncode;
284 failure:
285 return Liberrorcode; }
286
287
288 /* smolFreeSim */
smolFreeSim(simptr sim)289 extern CSTRING enum ErrorCode smolFreeSim(simptr sim) {
290 simfree(sim);
291 return ECok; }
292
293
294 /* smolDisplaySim */
smolDisplaySim(simptr sim)295 extern CSTRING enum ErrorCode smolDisplaySim(simptr sim) {
296 simsystemoutput(sim);
297 checksimparams(sim);
298 return ECok; }
299
300
301 /******************************************************************************/
302 /************************** Read configuration file ***************************/
303 /******************************************************************************/
304
305
306 /* smolPrepareSimFromFile */
smolPrepareSimFromFile(const char * filepath,const char * filename,const char * flags)307 extern CSTRING simptr smolPrepareSimFromFile(const char *filepath,const char *filename,const char *flags) {
308 const char *funcname="smolPrepareSimFromFile";
309 int er;
310 char emptystring[STRCHAR];
311 simptr sim;
312
313 sim=NULL;
314 LCHECK(filename,funcname,ECmissing,"missing filename");
315
316 emptystring[0]='\0';
317 if(!filepath) filepath=emptystring;
318 if(!flags) flags=emptystring;
319 #ifdef OPTION_VCELL
320 er=simInitAndLoad(filepath,filename,&sim,flags,new SimpleValueProviderFactory(),new SimpleMesh());
321 #else
322 er=simInitAndLoad(filepath,filename,&sim,flags);
323 #endif
324 LCHECKNT(!er,funcname,ECerror,ErrorLineAndString);
325 er=simUpdateAndDisplay(sim);
326 LCHECK(!er,funcname,ECerror,"Failed to update simulation");
327 return sim;
328 failure:
329 simfree(sim);
330 return NULL; }
331
332
333 /* smolLoadSimFromFile */
smolLoadSimFromFile(const char * filepath,const char * filename,simptr * simpointer,const char * flags)334 extern CSTRING enum ErrorCode smolLoadSimFromFile(const char *filepath,const char *filename,simptr *simpointer,const char *flags) {
335 const char *funcname="smolLoadSimFromFile";
336 int er;
337 char emptystring[STRCHAR];
338 simptr sim;
339
340 sim=NULL;
341 LCHECK(filename,funcname,ECmissing,"missing filename");
342 LCHECK(simpointer,funcname,ECmissing,"missing simpointer");
343
344 emptystring[0]='\0';
345 if(!filepath) filepath=emptystring;
346 if(!flags) flags=emptystring;
347
348 sim=*simpointer;
349 if(!sim) {
350 sim=simalloc(filepath);
351 LCHECK(sim,funcname,ECmemory,"allocating sim"); }
352 er=loadsim(sim,filepath,filename,flags);
353 LCHECKNT(!er,funcname,ECerror,ErrorLineAndString);
354
355 *simpointer=sim;
356 return ECok;
357 failure:
358 return Liberrorcode; }
359
360
361 /* smolReadConfigString */
smolReadConfigString(simptr sim,const char * statement,char * parameters)362 extern CSTRING enum ErrorCode smolReadConfigString(simptr sim,const char *statement,char *parameters) {
363 const char *funcname="smolReadConfigString";
364 int er;
365
366 LCHECK(sim,funcname,ECmissing,"missing sim");
367 LCHECK(statement,funcname,ECmissing,"missing statement");
368 er=simreadstring(sim,NULL,statement,parameters);
369 LCHECK(!er,funcname,ECerror,"Error in configuration string");
370
371 return ECok;
372 failure:
373 return Liberrorcode; }
374
375
376 /******************************************************************************/
377 /***************************** Simulation settings ****************************/
378 /******************************************************************************/
379
380
381 /* smolSetSimFlags */
smolSetSimFlags(simptr sim,const char * flags)382 extern CSTRING enum ErrorCode smolSetSimFlags(simptr sim,const char *flags) {
383 const char *funcname="smolSetSimFlags";
384
385 LCHECK(sim,funcname,ECmissing,"missing sim");
386 LCHECK(flags,funcname,ECmissing,"missing flags");
387 strncpy(sim->flags,flags,STRCHAR);
388 return ECok;
389 failure:
390 return Liberrorcode; }
391
392
393 /* smolSetSimTimes */
smolSetSimTimes(simptr sim,double timestart,double timestop,double timestep)394 extern CSTRING enum ErrorCode smolSetSimTimes(simptr sim,double timestart,double timestop,double timestep) {
395 const char *funcname="smolSetSimTimes";
396
397 LCHECK(sim,funcname,ECmissing,"missing sim");
398 LCHECK(timestep>0,funcname,ECbounds,"timestep value");
399 simsettime(sim,timestart,0);
400 simsettime(sim,timestart,1);
401 simsettime(sim,timestop,2);
402 simsettime(sim,timestep,3);
403 return ECok;
404 failure:
405 return Liberrorcode; }
406
407
408 /* smolSetTimeStart */
smolSetTimeStart(simptr sim,double timestart)409 extern CSTRING enum ErrorCode smolSetTimeStart(simptr sim,double timestart) {
410 const char *funcname="smolSetTimeStart";
411
412 LCHECK(sim,funcname,ECmissing,"missing sim");
413 simsettime(sim,timestart,1);
414 return ECok;
415 failure:
416 return Liberrorcode; }
417
418
419 /* smolSetTimeStop */
smolSetTimeStop(simptr sim,double timestop)420 extern CSTRING enum ErrorCode smolSetTimeStop(simptr sim,double timestop) {
421 const char *funcname="smolSetTimeStop";
422
423 LCHECK(sim,funcname,ECmissing,"missing sim");
424 simsettime(sim,timestop,2);
425 return ECok;
426 failure:
427 return Liberrorcode; }
428
429
430 /* smolSetTimeNow */
smolSetTimeNow(simptr sim,double timenow)431 extern CSTRING enum ErrorCode smolSetTimeNow(simptr sim,double timenow) {
432 const char *funcname="smolSetTimeNow";
433
434 LCHECK(sim,funcname,ECmissing,"missing sim");
435 simsettime(sim,timenow,0);
436 return ECok;
437 failure:
438 return Liberrorcode; }
439
440
441 /* smolSetTimeStep */
smolSetTimeStep(simptr sim,double timestep)442 extern CSTRING enum ErrorCode smolSetTimeStep(simptr sim,double timestep) {
443 const char *funcname="smolSetTimeStep";
444
445 LCHECK(sim,funcname,ECmissing,"missing sim");
446 LCHECK(timestep>0,funcname,ECbounds,"timestep is not > 0");
447 simsettime(sim,timestep,3);
448 return ECok;
449 failure:
450 return Liberrorcode; }
451
452
453 /* smolSetRandomSeed */
smolSetRandomSeed(simptr sim,long int seed)454 extern CSTRING enum ErrorCode smolSetRandomSeed(simptr sim,long int seed) {
455 const char *funcname="smolSetRandomSeed";
456
457 LCHECK(sim,funcname,ECmissing,"missing sim");
458 Simsetrandseed(sim,seed);
459 return ECok;
460 failure:
461 return Liberrorcode; }
462
463
464 /* smolSetPartitions */
smolSetPartitions(simptr sim,const char * method,double value)465 extern CSTRING enum ErrorCode smolSetPartitions(simptr sim,const char *method,double value) {
466 const char *funcname="smolSetPartitions";
467 int er;
468
469 LCHECK(sim,funcname,ECmissing,"missing sim");
470 LCHECK(method,funcname,ECmissing,"missing method string");
471 LCHECK(value>0,funcname,ECbounds,"value needs to be > 0");
472 er=boxsetsize(sim,method,value);
473 LCHECK(er!=1,funcname,ECmemory,"out of memory");
474 LCHECK(er!=2,funcname,ECsyntax,"method is not recognized");
475 return ECok;
476 failure:
477 return Liberrorcode; }
478
479
480 /******************************************************************************/
481 /********************************** Graphics **********************************/
482 /******************************************************************************/
483
484 /* smolSetGraphicsParams */
smolSetGraphicsParams(simptr sim,const char * method,int timesteps,int delay)485 extern CSTRING enum ErrorCode smolSetGraphicsParams(simptr sim,const char *method,int timesteps,int delay) {
486 const char *funcname="smolSetGraphicsParams";
487 int er;
488
489 LCHECK(sim,funcname,ECmissing,"missing sim");
490 er=graphicsenablegraphics(sim,method);
491 LCHECK(er!=1,funcname,ECmemory,"out of memory");
492 LCHECK(er!=2,funcname,ECmissing,"missing sim");
493 LCHECK(er!=3,funcname,ECsyntax,"graphics method not recognized");
494 if(timesteps>0) {
495 er=graphicssetiter(sim,timesteps);
496 LCHECK(er!=1,funcname,ECmemory,"out of memory enabling graphics");
497 LCHECK(er!=2,funcname,ECbug,"BUG: missing parameter");
498 LCHECK(er!=3,funcname,ECbug,"BUG: timesteps needs to be >=1"); }
499 if(delay>=0) {
500 er=graphicssetdelay(sim,delay);
501 LCHECK(er!=1,funcname,ECmemory,"out of memory enabling graphics");
502 LCHECK(er!=2,funcname,ECbug,"BUG: missing parameter");
503 LCHECK(er!=3,funcname,ECbug,"BUG: delay needs to be >=0"); }
504 return ECok;
505 failure:
506 return Liberrorcode; }
507
508
509 /* smolSetTiffParams */
smolSetTiffParams(simptr sim,int timesteps,const char * tiffname,int lowcount,int highcount)510 extern CSTRING enum ErrorCode smolSetTiffParams(simptr sim,int timesteps,const char *tiffname,int lowcount,int highcount) {
511 const char *funcname="smolSetTiffParams";
512 char nm1[STRCHAR];
513 int er;
514
515 LCHECK(sim,funcname,ECmissing,"missing sim");
516 if(timesteps>0) {
517 er=graphicssettiffiter(sim,timesteps);
518 LCHECK(er!=1,funcname,ECmemory,"out of memory enabling graphics");
519 LCHECK(er!=2,funcname,ECbug,"BUG: missing parameter");
520 LCHECK(er!=3,funcname,ECbug,"BUG: timesteps needs to be >=1"); }
521 if(tiffname) {
522 strcpy(nm1,sim->filepath);
523 strncat(nm1,tiffname,STRCHAR-1-strlen(nm1));
524 gl2SetOptionStr("TiffName",nm1); }
525 if(lowcount>=0) {
526 gl2SetOptionInt("TiffNumber",lowcount); }
527 if(highcount>=0) {
528 gl2SetOptionInt("TiffNumMax",highcount); }
529 return ECok;
530 failure:
531 return Liberrorcode; }
532
533
534 /* smolSetLightParams */
smolSetLightParams(simptr sim,int lightindex,double * ambient,double * diffuse,double * specular,double * position)535 extern CSTRING enum ErrorCode smolSetLightParams(simptr sim,int lightindex,double *ambient,double *diffuse,double *specular,double *position) {
536 const char *funcname="smolSetLightParams";
537 int c,er;
538
539 LCHECK(sim,funcname,ECmissing,"missing sim");
540 LCHECK(lightindex>=-1 && lightindex<MAXLIGHTS,funcname,ECbounds,"lightindex out of bounds");
541 LCHECK(lightindex>=0 || (!diffuse && !specular && !position),funcname,ECsyntax,"can only set ambient for global light");
542
543 if(ambient) {
544 for(c=0;c<4;c++)
545 LCHECK(ambient[c]>=0 && ambient[c]<=1,funcname,ECbounds,"ambient light value out of bounds");
546 er=graphicssetlight(sim,NULL,lightindex,LPambient,ambient);
547 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
548 if(diffuse) {
549 for(c=0;c<4;c++)
550 LCHECK(diffuse[c]>=0 && diffuse[c]<=1,funcname,ECbounds,"diffuse light value out of bounds");
551 er=graphicssetlight(sim,NULL,lightindex,LPdiffuse,diffuse);
552 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
553 if(specular) {
554 for(c=0;c<4;c++)
555 LCHECK(specular[c]>=0 && specular[c]<=1,funcname,ECbounds,"specular light value out of bounds");
556 er=graphicssetlight(sim,NULL,lightindex,LPspecular,specular);
557 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
558 if(position) {
559 er=graphicssetlight(sim,NULL,lightindex,LPposition,position);
560 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
561
562 return ECok;
563 failure:
564 return Liberrorcode; }
565
566
567 /* smolSetBackgroundStyle */
smolSetBackgroundStyle(simptr sim,double * color)568 extern CSTRING enum ErrorCode smolSetBackgroundStyle(simptr sim,double *color) {
569 const char *funcname="smolSetBackgroundStyle";
570 int c,er;
571
572 LCHECK(sim,funcname,ECmissing,"missing sim");
573 if(color) {
574 for(c=0;c<4;c++)
575 LCHECK(color[c]>=0 && color[c]<=1,funcname,ECbounds,"color value out of bounds");
576 er=graphicssetbackcolor(sim,color);
577 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
578 return ECok;
579 failure:
580 return Liberrorcode; }
581
582
583 /* smolSetFrameStyle */
smolSetFrameStyle(simptr sim,double thickness,double * color)584 extern CSTRING enum ErrorCode smolSetFrameStyle(simptr sim,double thickness,double *color) {
585 const char *funcname="smolSetFrameStyle";
586 int c,er;
587
588 LCHECK(sim,funcname,ECmissing,"missing sim");
589 if(thickness>=0) {
590 er=graphicssetframethickness(sim,thickness);
591 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
592 if(color) {
593 for(c=0;c<4;c++)
594 LCHECK(color[c]>=0 && color[c]<=1,funcname,ECbounds,"color value out of bounds");
595 er=graphicssetframecolor(sim,color);
596 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
597 return ECok;
598 failure:
599 return Liberrorcode; }
600
601
602 /* smolSetGridStyle */
smolSetGridStyle(simptr sim,double thickness,double * color)603 extern CSTRING enum ErrorCode smolSetGridStyle(simptr sim,double thickness,double *color) {
604 const char *funcname="smolSetGridStyle";
605 int c,er;
606
607 LCHECK(sim,funcname,ECmissing,"missing sim");
608 if(thickness>=0) {
609 er=graphicssetgridthickness(sim,thickness);
610 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
611 if(color) {
612 for(c=0;c<4;c++)
613 LCHECK(color[c]>=0 && color[c]<=1,funcname,ECbounds,"color value out of bounds");
614 er=graphicssetgridcolor(sim,color);
615 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
616 return ECok;
617 failure:
618 return Liberrorcode; }
619
620
621 /* smolSetTextStyle */
smolSetTextStyle(simptr sim,double * color)622 extern CSTRING enum ErrorCode smolSetTextStyle(simptr sim,double *color) {
623 const char *funcname="smolSetTextStyle";
624 int c,er;
625
626 LCHECK(sim,funcname,ECmissing,"missing sim");
627 if(color) {
628 for(c=0;c<4;c++)
629 LCHECK(color[c]>=0 && color[c]<=1,funcname,ECbounds,"color value out of bounds");
630 er=graphicssettextcolor(sim,color);
631 LCHECK(!er,funcname,ECmemory,"out of memory enabling graphics"); }
632 return ECok;
633 failure:
634 return Liberrorcode; }
635
636
637 /* smolAddTextDisplay */
smolAddTextDisplay(simptr sim,char * item)638 extern CSTRING enum ErrorCode smolAddTextDisplay(simptr sim,char *item) {
639 const char *funcname="smolAddTextDisplay";
640 int er;
641
642 LCHECK(sim,funcname,ECmissing,"missing sim");
643 er=graphicssettextitem(sim,item);
644 LCHECK(er!=1,funcname,ECmemory,"out of memory adding text display item");
645 LCHECK(er!=2,funcname,ECsyntax,"listed item is not recognized or not supported");
646 LCHECK(er!=3,funcname,ECwarning,"text display item was already listed");
647 return Libwarncode;
648 failure:
649 return Liberrorcode; }
650
651
652 /******************************************************************************/
653 /***************************** Runtime commands *******************************/
654 /******************************************************************************/
655
656 /* smolSetOutputPath */
smolSetOutputPath(simptr sim,const char * path)657 extern CSTRING enum ErrorCode smolSetOutputPath(simptr sim,const char *path) {
658 const char *funcname="smolSetOutputPath";
659 int er;
660
661 LCHECK(sim,funcname,ECmissing,"missing sim");
662 LCHECK(path,funcname,ECmissing,"missing path");
663 er=scmdsetfroot(sim->cmds,path);
664 LCHECK(!er,funcname,ECbug,"scmdsetfroot bug");
665 return ECok;
666 failure:
667 return Liberrorcode; }
668
669
670 /* smolAddOutputFile */
smolAddOutputFile(simptr sim,char * filename,int suffix,int append)671 extern CSTRING enum ErrorCode smolAddOutputFile(simptr sim,char *filename,int suffix,int append) {
672 const char *funcname="smolAddOutputFile";
673 int er;
674
675 LCHECK(sim,funcname,ECmissing,"missing sim");
676 LCHECK(filename,funcname,ECmissing,"missing filename");
677 LCHECK(!strchr(filename,' '),funcname,ECwarning,"only first word of filename is used");
678 er=scmdsetfnames(sim->cmds,filename,append);
679 LCHECK(!er,funcname,ECmemory,"allocating filename");
680 if(suffix>=0) {
681 er=scmdsetfsuffix(sim->cmds,filename,suffix);
682 LCHECK(!er,funcname,ECbug,"scmdsetfsuffix bug"); }
683
684 return Libwarncode;
685 failure:
686 return Liberrorcode; }
687
688
689 /* smolAddOutputData */
smolAddOutputData(simptr sim,char * dataname)690 extern CSTRING enum ErrorCode smolAddOutputData(simptr sim,char *dataname) {
691 const char *funcname="smolAddOutputData";
692 int er;
693
694 LCHECK(sim,funcname,ECmissing,"missing sim");
695 LCHECK(dataname,funcname,ECmissing,"missing dataname");
696 LCHECK(!strchr(dataname,' '),funcname,ECwarning,"only first word of dataname is used");
697 er=scmdsetdnames(sim->cmds,dataname);
698 LCHECK(!er,funcname,ECmemory,"allocating dataname");
699 return Libwarncode;
700 failure:
701 return Liberrorcode; }
702
703
704 /* smolOpenOutputFiles */
smolOpenOutputFiles(simptr sim,int overwrite=0)705 enum ErrorCode smolOpenOutputFiles(simptr sim, int overwrite = 0)
706 {
707 const char *funcname = "smolOpenOutputFiles";
708 int err = scmdopenfiles(sim->cmds, overwrite);
709 LCHECK(!err, funcname, ECerror, "Unable (or forbidden) to open output files for writing");
710
711 return Libwarncode;
712 failure:
713 return Liberrorcode;
714 }
715
716 /* smolAddCommand */
smolAddCommand(simptr sim,char type,double on,double off,double step,double multiplier,const char * commandstring)717 extern CSTRING enum ErrorCode smolAddCommand(simptr sim,char type,double on,double off,double step,double multiplier,const char *commandstring) {
718 const char *funcname="smolSetCommand";
719 int er;
720
721 LCHECK(sim,funcname,ECmissing,"missing sim");
722 er=scmdaddcommand(sim->cmds,type,on,off,step,multiplier,commandstring);
723 LCHECK(er!=1,funcname,ECmemory,"out of memory creating command");
724 LCHECK(er!=2,funcname,ECbug,"missing sim->cmds");
725 LCHECK(er!=3,funcname,ECsyntax,"missing command string");
726 return ECok;
727 failure:
728 return Liberrorcode; }
729
730
731 /* smolAddCommandFromString */
smolAddCommandFromString(simptr sim,char * string)732 extern CSTRING enum ErrorCode smolAddCommandFromString(simptr sim,char *string) {
733 const char *funcname="smolSetCommandFromString";
734 int er;
735
736 LCHECK(sim,funcname,ECmissing,"missing sim");
737 LCHECK(string,funcname,ECmissing,"missing string");
738 er=scmdstr2cmd(sim->cmds,string,NULL,NULL,0);
739 LCHECK(er!=1,funcname,ECmemory,"out of memory in cmd");
740 LCHECK(er!=2,funcname,ECbug,"BUG: no command superstructure for cmd");
741 LCHECK(er!=3,funcname,ECsyntax,"cmd format: type [on off dt] string");
742 LCHECK(er!=5,funcname,ECbounds,"cmd time step needs to be >0");
743 LCHECK(er!=8,funcname,ECbounds,"cmd time multiplier needs to be >1");
744 return ECok;
745 failure:
746 return Liberrorcode; }
747
748
749 /* smolGetOutputData */
smolGetOutputData(simptr sim,char * dataname,int * nrow,int * ncol,double ** array,int erase)750 extern CSTRING enum ErrorCode smolGetOutputData(simptr sim,char *dataname,int *nrow,int *ncol,double **array,int erase) {
751 const char *funcname="smolGetOutputData";
752 int did,i,j;
753 listptrdd list;
754 double *datacopy;
755
756 LCHECK(sim,funcname,ECmissing,"missing sim");
757 LCHECK(dataname,funcname,ECmissing,"missing dataname");
758 LCHECK(nrow && ncol && array,funcname,ECmissing,"missing pointer for returned data");
759 LCHECK(sim->cmds && sim->cmds->ndata>0,funcname,ECerror,"no data files in the sim");
760 did=stringfind(sim->cmds->dname,sim->cmds->ndata,dataname);
761 LCHECK(did>=0,funcname,ECerror,"no data file of the requested name");
762 list=sim->cmds->data[did];
763
764 datacopy=(double*) calloc(list->nrow*list->ncol,sizeof(double));
765 LCHECK(datacopy,funcname,ECmemory,"out of memory");
766 for(i=0;i<list->nrow;i++)
767 for(j=0;j<list->ncol;j++)
768 datacopy[i*list->ncol+j]=list->data[i*list->maxcol+j];
769 *nrow=list->nrow;
770 *ncol=list->ncol;
771 *array=datacopy;
772 if(erase) ListClearDD(list);
773
774 return ECok;
775 failure:
776 return Liberrorcode; }
777
778
smolRunCommand(simptr sim,const char * commandstring)779 extern CSTRING enum ErrorCode smolRunCommand(simptr sim,const char *commandstring) {
780 const char *funcname="smolRunCommand";
781 char stringcopy[STRCHAR];
782 cmdptr cmd;
783 enum CMDcode cmdcode;
784
785 LCHECK(sim,funcname,ECmissing,"missing sim");
786 LCHECK(commandstring,funcname,ECmissing,"missing command string");
787 strncpy(stringcopy,commandstring,STRCHAR-1);
788 cmd=scmdalloc();
789 LCHECK(cmd,funcname,ECmemory,"failed to create a new command structure");
790 strcpy(cmd->str,stringcopy);
791 cmdcode=docommand((void*)sim,cmd,stringcopy);
792 LCHECK(cmdcode==CMDok,funcname,ECwarning,cmd->erstr);
793 scmdfree(cmd);
794 return ECok;
795 failure:
796 return Liberrorcode; }
797
798
799 /******************************************************************************/
800 /********************************* Molecules **********************************/
801 /******************************************************************************/
802
803 /* smolAddSpecies */
smolAddSpecies(simptr sim,const char * species,const char * mollist)804 extern CSTRING enum ErrorCode smolAddSpecies(simptr sim,const char *species,const char *mollist) {
805 const char *funcname="smolAddSpecies";
806 int i,ll;
807
808 LCHECK(sim,funcname,ECmissing,"missing sim");
809 LCHECK(species,funcname,ECmissing,"missing species");
810 if(mollist && mollist[0]!='\0') {
811 ll=smolGetMolListIndexNT(sim,mollist);
812 LCHECK(ll>=0,funcname,ECsame,NULL);
813 LCHECK(sim->mols->listtype[ll]==MLTsystem,funcname,ECsyntax,"mollist is not a system list"); }
814 else ll=-1;
815 i=moladdspecies(sim,species);
816 LCHECK(i!=-1,funcname,ECbug,"out of memory");
817 LCHECK(i!=-2,funcname,ECbug,"add species bug");
818 LCHECK(i!=-3,funcname,ECbug,"more species are entered than are automatically allocated");
819 LCHECK(i!=-4,funcname,ECsyntax,"'empty' is not a permitted species name");
820 LCHECK(i!=-5,funcname,ECwarning,"this species has already been declared");
821 LCHECK(i!=-6,funcname,ECsyntax,"'?' and '*' are not allowed in species names");
822 if(mollist && mollist[0]!='\0')
823 molsetlistlookup(sim,i,NULL,MSall,ll);
824 return Libwarncode;
825 failure:
826 return Liberrorcode; }
827
828
829 /* smolGetSpeciesIndex */
smolGetSpeciesIndex(simptr sim,const char * species)830 extern CSTRING int smolGetSpeciesIndex(simptr sim,const char *species) {
831 const char *funcname="smolGetSpeciesIndex";
832 int i;
833
834 LCHECK(sim,funcname,ECmissing,"missing sim");
835 LCHECK(species,funcname,ECmissing,"missing species name");
836 LCHECK(sim->mols,funcname,ECnonexist,"no species defined");
837 LCHECK(strcmp(species,"all"),funcname,ECall,"species is 'all'");
838 i=stringfind(sim->mols->spname,sim->mols->nspecies,species);
839 if(i<=0) {
840 char buffer[STRCHAR];
841 snprintf(buffer,STRCHAR,"species '%s' not found",species);
842 LCHECK(0,funcname,ECnonexist,buffer); }
843 return i;
844 failure:
845 return (int)Liberrorcode; }
846
847
848 /* smolGetSpeciesIndexNT */
smolGetSpeciesIndexNT(simptr sim,const char * species)849 extern CSTRING int smolGetSpeciesIndexNT(simptr sim,const char *species) {
850 const char *funcname="smolGetSpeciesIndexNT";
851 int i;
852
853 LCHECKNT(sim,funcname,ECmissing,"missing sim");
854 LCHECKNT(species,funcname,ECmissing,"missing species name");
855 LCHECKNT(sim->mols,funcname,ECnonexist,"no species defined");
856 LCHECKNT(strcmp(species,"all"),funcname,ECall,"species cannot be 'all'");
857 i=stringfind(sim->mols->spname,sim->mols->nspecies,species);
858 if(i<=0) {
859 char buffer[STRCHAR];
860 snprintf(buffer,STRCHAR,"species '%s' not found",species);
861 LCHECKNT(0,funcname,ECnonexist,buffer); }
862 return i;
863 failure:
864 return (int)Liberrorcode; }
865
866
867 /* smolGetSpeciesName */
smolGetSpeciesName(simptr sim,int speciesindex,char * species)868 extern CSTRING void smolGetSpeciesName(simptr sim,int speciesindex,char *species) {
869 const char *funcname="smolGetSpeciesName";
870
871 LCHECK(sim,funcname,ECmissing,"missing sim");
872 LCHECK(sim->mols,funcname,ECnonexist,"no species defined");
873 LCHECK(speciesindex>=0,funcname,ECbounds,"speciesindex < 0");
874 LCHECK(speciesindex<sim->mols->nspecies,funcname,ECnonexist,"species doesn't exist");
875 LCHECK(species,funcname,ECmissing,"missing species");
876 strcpy(species,sim->mols->spname[speciesindex]);
877 failure:
878 return; }
879
880
881 /* smolGetSpecies */
smolGetSpecies(simptr sim,int speciesindex,char * speciesname,double * difc,double ** color,double * displaysize,char ** listname)882 extern CSTRING int smolGetSpecies(simptr sim,int speciesindex,char *speciesname,double *difc,double **color,double *displaysize,char **listname) {
883 const char *funcname="smolGetSpecies";
884 int i=0;
885 enum MolecState ms;
886
887 LCHECK(sim,funcname,ECmissing,"missing sim");
888 LCHECK(sim->mols,funcname,ECnonexist,"no species defined");
889 if(speciesindex>=0) {
890 LCHECK(speciesindex<sim->mols->nspecies,funcname,ECnonexist,"species doesn't exist");
891 if(speciesname) strcpy(speciesname,sim->mols->spname[speciesindex]); }
892 else {
893 LCHECK(speciesname,funcname,ECmissing,"missing species name");
894 LCHECK(strcmp(speciesname,"all"),funcname,ECall,"species is 'all'");
895 i=stringfind(sim->mols->spname,sim->mols->nspecies,speciesname);
896 if(i<=0) {
897 char buffer[STRCHAR];
898 snprintf(buffer,STRCHAR,"species '%s' not found",speciesname);
899 LCHECK(0,funcname,ECnonexist,buffer); }}
900 for(ms=(enum MolecState)0;ms<(enum MolecState)MSMAX;ms=(enum MolecState)(ms+1)) {
901 if(difc) difc[ms]=sim->mols->difc[i][ms];
902 if(color) {
903 color[ms][0]=sim->mols->color[i][ms][0];
904 color[ms][1]=sim->mols->color[i][ms][1];
905 color[ms][2]=sim->mols->color[i][ms][2];
906 color[ms][3]=sim->mols->color[i][ms][3]; }
907 if(displaysize) displaysize[ms]=sim->mols->display[i][ms];
908 if(listname) strcpy(listname[ms],sim->mols->listname[sim->mols->listlookup[i][ms]]); }
909 return i;
910 failure:
911 return (int)Liberrorcode; }
912
913
914 /* smolSetSpeciesMobility */
smolSetSpeciesMobility(simptr sim,const char * species,enum MolecState state,double difc,double * drift,double * difmatrix)915 extern CSTRING enum ErrorCode smolSetSpeciesMobility(simptr sim,const char *species,enum MolecState state,double difc,double *drift,double *difmatrix) {
916 const char *funcname="smolSetSpeciesMobility";
917 int i,er,isall,ilow,ihigh;
918
919 LCHECK(sim,funcname,ECmissing,"missing sim");
920 LCHECK(sim->mols,funcname,ECnonexist,"no species defined");
921 isall=0;
922 i=smolGetSpeciesIndexNT(sim,species);
923 if(i==(int)ECall) {smolClearError();isall=1;}
924 else LCHECK(i>0,funcname,ECsame,NULL);
925 LCHECK((state>=0 && state<MSMAX) || state==MSall,funcname,ECsyntax,"invalid state");
926
927 if(isall) {
928 ilow=1;
929 ihigh=sim->mols->nspecies; }
930 else {
931 ilow=i;
932 ihigh=i+1; }
933
934 for(i=ilow;i<ihigh;i++) {
935 if(difc>=0) {
936 molsetdifc(sim,i,NULL,state,difc); }
937 if(drift) {
938 er=molsetdrift(sim,i,NULL,state,drift);
939 LCHECK(!er,funcname,ECmemory,"allocating drift"); }
940 if(difmatrix) {
941 er=molsetdifm(sim,i,NULL,state,difmatrix);
942 LCHECK(!er,funcname,ECmemory,"allocating difmatrix"); }}
943
944 return ECok;
945 failure:
946 return Liberrorcode; }
947
948
949 //?? need to add function for smolSetSpeciesSurfaceDrift
950
951
952 /* smolAddMolList */
smolAddMolList(simptr sim,const char * mollist)953 extern CSTRING enum ErrorCode smolAddMolList(simptr sim,const char *mollist) {
954 const char *funcname="smolAddMolList";
955 int ll;
956
957 LCHECK(sim,funcname,ECmissing,"missing sim");
958 LCHECK(mollist,funcname,ECmissing,"missing mollist");
959 ll=addmollist(sim,mollist,MLTsystem);
960 LCHECK(ll!=-1,funcname,ECmemory,"out of memory");
961 LCHECK(ll!=-2,funcname,ECwarning,"molecule list name has already been used");
962 LCHECK(ll!=-3,funcname,ECbug,"illegal addmollist inputs");
963 return Libwarncode;
964 failure:
965 return Liberrorcode; }
966
967
968 /* smolGetMolListIndex */
smolGetMolListIndex(simptr sim,const char * mollist)969 extern CSTRING int smolGetMolListIndex(simptr sim,const char *mollist) {
970 const char *funcname="smolGetMolListIndex";
971 int ll;
972
973 LCHECK(sim,funcname,ECmissing,"missing sim");
974 LCHECK(mollist,funcname,ECmissing,"missing mollist");
975 LCHECK(sim->mols,funcname,ECnonexist,"no molecule lists defined");
976 LCHECK(strcmp(mollist,"all"),funcname,ECall,"molecule list is 'all'");
977 ll=stringfind(sim->mols->listname,sim->mols->nlist,mollist);
978 LCHECK(ll>=0,funcname,ECnonexist,"list name not recognized");
979 return ll;
980 failure:
981 return (int)Liberrorcode; }
982
983
984 /* smolGetMolListIndexNT */
smolGetMolListIndexNT(simptr sim,const char * mollist)985 extern CSTRING int smolGetMolListIndexNT(simptr sim,const char *mollist) {
986 const char *funcname="smolGetMolListIndexNT";
987 int ll;
988
989 LCHECKNT(sim,funcname,ECmissing,"missing sim");
990 LCHECKNT(mollist,funcname,ECmissing,"missing mollist");
991 LCHECKNT(sim->mols,funcname,ECnonexist,"no molecule lists defined");
992 LCHECKNT(strcmp(mollist,"all"),funcname,ECall,"molecule list cannot be 'all'");
993 ll=stringfind(sim->mols->listname,sim->mols->nlist,mollist);
994 LCHECKNT(ll>=0,funcname,ECnonexist,"list name not recognized");
995 return ll;
996 failure:
997 return (int)Liberrorcode; }
998
999
1000 /* smolGetMolListName */
smolGetMolListName(simptr sim,int mollistindex,char * mollist)1001 extern CSTRING char *smolGetMolListName(simptr sim,int mollistindex,char *mollist) {
1002 const char *funcname="smolGetMolListName";
1003
1004 LCHECK(sim,funcname,ECmissing,"missing sim");
1005 LCHECK(mollistindex>=0,funcname,ECbounds,"mollistindex < 0");
1006 LCHECK(sim->mols,funcname,ECnonexist,"no molecule lists defined");
1007 LCHECK(mollistindex<sim->mols->nlist,funcname,ECnonexist,"molecule list doesn't exist");
1008 LCHECK(mollist,funcname,ECmissing,"missing mollist");
1009 strcpy(mollist,sim->mols->listname[mollistindex]);
1010 return mollist;
1011 failure:
1012 return NULL; }
1013
1014
1015 /* smolSetMolList */
smolSetMolList(simptr sim,const char * species,enum MolecState state,const char * mollist)1016 extern CSTRING enum ErrorCode smolSetMolList(simptr sim,const char *species,enum MolecState state,const char *mollist) {
1017 const char *funcname="smolSetMolList";
1018 int i,ll;
1019
1020 LCHECK(sim,funcname,ECmissing,"missing sim");
1021 i=smolGetSpeciesIndexNT(sim,species);
1022 if(i==(int)ECall) {smolClearError();i=-5;}
1023 else LCHECK(i>0,funcname,ECsame,NULL);
1024 LCHECK((state>=0 && state<MSMAX) || state==MSall,funcname,ECsyntax,"invalid state");
1025 ll=smolGetMolListIndexNT(sim,mollist);
1026 LCHECK(ll>=0,funcname,ECsame,NULL);
1027 LCHECK(sim->mols->listtype[ll]==MLTsystem,funcname,ECerror,"list is not a system list");
1028 molsetlistlookup(sim,i,NULL,state,ll);
1029 return ECok;
1030 failure:
1031 return Liberrorcode; }
1032
1033
1034 /* smolSetMaxMolecules */
smolSetMaxMolecules(simptr sim,int maxmolecules)1035 extern CSTRING enum ErrorCode smolSetMaxMolecules(simptr sim,int maxmolecules) {
1036 const char *funcname="smolSetMaxMolecules";
1037 int er;
1038
1039 LCHECK(sim,funcname,ECmissing,"missing sim");
1040 LCHECK(maxmolecules>0,funcname,ECbounds,"maxmolecules needs to be > 0");
1041 er=molsetmaxmol(sim,maxmolecules);
1042 LCHECK(!er,funcname,ECmemory,"out of memory allocating molecules");
1043 return ECok;
1044 failure:
1045 return Liberrorcode; }
1046
1047
1048 /* smolAddSolutionMolecules */
smolAddSolutionMolecules(simptr sim,const char * species,int number,double * lowposition,double * highposition)1049 extern CSTRING enum ErrorCode smolAddSolutionMolecules(simptr sim,const char *species,int number,double *lowposition,double *highposition) {
1050 const char *funcname="smolAddSolutionMolecules";
1051 int er,i,d;
1052 double *low,*high,lowpos[3],highpos[3];
1053
1054 LCHECK(sim,funcname,ECmissing,"missing sim");
1055 i=smolGetSpeciesIndexNT(sim,species);
1056 LCHECK(i>0,funcname,ECsame,NULL);
1057 LCHECK(number>=0,funcname,ECbounds,"number cannot be < 0");
1058 if(!lowposition) {
1059 for(d=0;d<sim->dim;d++) lowpos[d]=sim->wlist[d*2]->pos;
1060 low=lowpos; }
1061 else
1062 low=lowposition;
1063 if(!highposition) {
1064 for(d=0;d<sim->dim;d++) highpos[d]=sim->wlist[d*2+1]->pos;
1065 high=highpos; }
1066 else
1067 high=highposition;
1068
1069 er=addmol(sim,number,i,low,high,0);
1070 LCHECK(!er,funcname,ECmemory,"out of memory adding molecules");
1071 return ECok;
1072 failure:
1073 return Liberrorcode; }
1074
1075
1076 /* smolAddCompartmentMolecules */
smolAddCompartmentMolecules(simptr sim,const char * species,int number,const char * compartment)1077 extern CSTRING enum ErrorCode smolAddCompartmentMolecules(simptr sim,const char *species,int number,const char *compartment) {
1078 const char *funcname="smolAddCompartmentMolecules";
1079 int i,er,c;
1080
1081 LCHECK(sim,funcname,ECmissing,"missing sim");
1082 i=smolGetSpeciesIndexNT(sim,species);
1083 LCHECK(i>0,funcname,ECsame,NULL);
1084 LCHECK(number>=0,funcname,ECbounds,"number < 0");
1085 c=smolGetCompartmentIndexNT(sim,compartment);
1086 LCHECK(c>=0,funcname,ECsame,NULL);
1087 er=addcompartmol(sim,number,i,sim->cmptss->cmptlist[c]);
1088 LCHECK(er!=2,funcname,ECerror,"compartment volume is zero or nearly zero");
1089 LCHECK(er!=3,funcname,ECmemory,"out of memory adding molecules");
1090 return ECok;
1091 failure:
1092 return Liberrorcode; }
1093
1094
1095 /* smolAddSurfaceMolecules */
smolAddSurfaceMolecules(simptr sim,const char * species,enum MolecState state,int number,const char * surface,enum PanelShape panelshape,const char * panel,double * position)1096 extern CSTRING enum ErrorCode smolAddSurfaceMolecules(simptr sim,const char *species,enum MolecState state,int number,const char *surface,enum PanelShape panelshape,const char *panel,double *position) {
1097 const char *funcname="smolAddSurfaceMolecules";
1098 int i,s,p,er;
1099 panelptr pnl;
1100
1101 LCHECK(sim,funcname,ECmissing,"missing sim");
1102 i=smolGetSpeciesIndexNT(sim,species);
1103 LCHECK(i>0,funcname,ECsame,NULL);
1104 LCHECK(state>=0 && state<MSMAX,funcname,ECsyntax,"invalid state");
1105 LCHECK(number>=0,funcname,ECbounds,"number < 0");
1106 s=smolGetSurfaceIndexNT(sim,surface);
1107 if(s==(int)ECall) {smolClearError();s=-5;}
1108 else LCHECK(s>=0,funcname,ECsame,NULL);
1109 LCHECK((panelshape>=0 && panelshape<PSMAX) || panelshape==PSall,funcname,ECnonexist,"invalid panelshape");
1110 pnl=NULL;
1111 p=smolGetPanelIndexNT(sim,surface,NULL,panel);
1112 if(p==(int)ECall) {smolClearError();p=-5;}
1113 else LCHECK(p>=0,funcname,ECsame,NULL);
1114
1115 if(p>=0) {
1116 LCHECK(s>=0,funcname,ECsyntax,"needs to be specific surface");
1117 LCHECK(panelshape!=PSall,funcname,ECsyntax,"needs to be specific panelshape");
1118 pnl=sim->srfss->srflist[s]->panels[panelshape][p]; }
1119 else {
1120 LCHECK(!position,funcname,ECsyntax,"a panel must be specified if position is entered"); }
1121 er=addsurfmol(sim,number,i,state,position,pnl,s,panelshape,NULL);
1122 LCHECK(er!=1,funcname,ECmemory,"unable to allocate temporary storage space");
1123 LCHECK(er!=2,funcname,ECbug,"panel name not recognized");
1124 LCHECK(er!=3,funcname,ECmemory,"out of memory adding molecules");
1125
1126 return ECok;
1127 failure:
1128 return Liberrorcode; }
1129
1130
1131 /* smolGetMoleculeCount */
smolGetMoleculeCount(simptr sim,const char * species,enum MolecState state)1132 extern CSTRING int smolGetMoleculeCount(simptr sim,const char *species,enum MolecState state) {
1133 const char *funcname="smolGetMoleculeCount";
1134 int i;
1135
1136 LCHECK(sim,funcname,ECmissing,"missing sim");
1137 i=smolGetSpeciesIndexNT(sim,species);
1138 if(i==(int)ECall) {i=-5;smolClearError();}
1139 else LCHECK(i>0,funcname,ECsame,NULL);
1140 return molcount(sim,i,NULL,state,-1);
1141 failure:
1142 return (int)Liberrorcode; }
1143
1144
1145 /* smolSetMoleculeColor */
smolSetMoleculeColor(simptr sim,const char * species,enum MolecState state,double * color)1146 extern "C" enum ErrorCode smolSetMoleculeColor(
1147 simptr sim, const char *species, enum MolecState state, double *color)
1148 {
1149 const char *funcname = "smolSetMoleculeColor";
1150 int i, c;
1151
1152 LCHECK(sim, funcname, ECmissing, "missing sim");
1153 i = smolGetSpeciesIndexNT(sim, species);
1154 if(i == (int)ECall) {
1155 smolClearError();
1156 i = -5;
1157 }
1158 else
1159 LCHECK(i > 0, funcname, ECsame, NULL);
1160
1161 LCHECK((state >= 0 && state < MSMAX) || state == MSall, funcname, ECsyntax,
1162 "invalid state");
1163
1164 for(c = 0; c < 3; c++)
1165 LCHECK(color[c] >= 0 && color[c] <= 1, funcname, ECbounds,
1166 "color value out of bounds");
1167 molsetcolor(sim, i, NULL, state, color);
1168 return ECok;
1169 failure:
1170 return Liberrorcode;
1171 }
1172
smolSetMoleculeSize(simptr sim,const char * species,enum MolecState state,double size)1173 extern "C" enum ErrorCode smolSetMoleculeSize(
1174 simptr sim, const char *species, enum MolecState state, double size)
1175 {
1176 const char *funcname = "smolSetMoleculeSize";
1177 int i;
1178 LCHECK(sim, funcname, ECmissing, "missing sim");
1179 i = smolGetSpeciesIndexNT(sim, species);
1180 if(i == (int)ECall) {
1181 smolClearError();
1182 i = -5;
1183 }
1184 else
1185 LCHECK(i > 0, funcname, ECsame, NULL);
1186 LCHECK((state >= 0 && state < MSMAX) || state == MSall, funcname, ECsyntax,
1187 "invalid state");
1188
1189 molsetdisplaysize(sim, i, NULL, state, size);
1190 return ECok;
1191 failure:
1192 return Liberrorcode;
1193 }
1194
1195 /* smolSetMoleculeStyle */
smolSetMoleculeStyle(simptr sim,const char * species,enum MolecState state,double size,double * color)1196 extern CSTRING enum ErrorCode smolSetMoleculeStyle(simptr sim,const char *species,enum MolecState state,double size,double *color) {
1197 const char *funcname="smolSetTextStyle";
1198 int i,c;
1199
1200 LCHECK(sim,funcname,ECmissing,"missing sim");
1201 i=smolGetSpeciesIndexNT(sim,species);
1202 if(i==(int)ECall) {smolClearError();i=-5;}
1203 else LCHECK(i>0,funcname,ECsame,NULL);
1204 LCHECK((state>=0 && state<MSMAX) || state==MSall,funcname,ECsyntax,"invalid state");
1205
1206 if(size>0) molsetdisplaysize(sim,i,NULL,state,size);
1207
1208 if(color) {
1209 for(c=0;c<3;c++)
1210 LCHECK(color[c]>=0 && color[c]<=1,funcname,ECbounds,"color value out of bounds");
1211 molsetcolor(sim,i,NULL,state,color); }
1212 return ECok;
1213 failure:
1214 return Liberrorcode; }
1215
1216
1217 /******************************************************************************/
1218 /*********************************** Surfaces *********************************/
1219 /******************************************************************************/
1220
1221 /* smolSetBoundaryType */
smolSetBoundaryType(simptr sim,int dimension,int highside,char type)1222 extern CSTRING enum ErrorCode smolSetBoundaryType(simptr sim,int dimension,int highside,char type) {
1223 const char *funcname="smolSetBoundaryType";
1224 int er;
1225
1226 LCHECK(sim,funcname,ECmissing,"missing sim");
1227 LCHECK(dimension<sim->dim,funcname,ECbounds,"dimension cannot exceed system dimensionality");
1228 LCHECK(highside<=1,funcname,ECbounds,"highside must be -1, 0, or 1");
1229 LCHECK(type=='r' || type=='p' || type=='a' || type=='t',funcname,ECsyntax,"invalid type");
1230 er=wallsettype(sim,dimension,highside,type);
1231 LCHECK(!er,funcname,ECbug,"bug in wallsettype");
1232 return ECok;
1233 failure:
1234 return Liberrorcode; }
1235
1236
1237 /* smolAddSurface */
smolAddSurface(simptr sim,const char * surface)1238 extern CSTRING enum ErrorCode smolAddSurface(simptr sim,const char *surface) {
1239 const char *funcname="smolAddSurface";
1240 int s;
1241 surfaceptr srf;
1242
1243 LCHECK(sim,funcname,ECmissing,"missing sim");
1244 s=smolGetSurfaceIndexNT(sim,surface);
1245 if(s==(int)ECnonexist) smolClearError();
1246 else if(s<0) LCHECK(0,funcname,ECsame,NULL);
1247 else LCHECK(0,funcname,ECerror,"surface is already in system");
1248 srf=surfaddsurface(sim,surface);
1249 LCHECK(srf,funcname,ECmemory,"out of memory adding surface");
1250 return ECok;
1251 failure:
1252 return Liberrorcode; }
1253
1254
1255 /* smolGetSurfaceIndex */
smolGetSurfaceIndex(simptr sim,const char * surface)1256 extern CSTRING int smolGetSurfaceIndex(simptr sim,const char *surface) {
1257 const char *funcname="smolGetSurfaceIndex";
1258 int s;
1259
1260 LCHECK(sim,funcname,ECmissing,"missing sim");
1261 LCHECK(surface,funcname,ECmissing,"missing surface");
1262 LCHECK(sim->srfss && sim->srfss->nsrf,funcname,ECnonexist,"no surfaces defined");
1263 LCHECK(strcmp(surface,"all"),funcname,ECall,"surface cannot be 'all'");
1264 s=stringfind(sim->srfss->snames,sim->srfss->nsrf,surface);
1265 LCHECK(s>=0,funcname,ECnonexist,"surface not found");
1266 return s;
1267 failure:
1268 return (int)Liberrorcode; }
1269
1270
1271 /* smolGetSurfaceIndexNT */
smolGetSurfaceIndexNT(simptr sim,const char * surface)1272 extern CSTRING int smolGetSurfaceIndexNT(simptr sim,const char *surface) {
1273 const char *funcname="smolGetSurfaceIndexNT";
1274 int s;
1275
1276 LCHECKNT(sim,funcname,ECmissing,"missing sim");
1277 LCHECKNT(surface,funcname,ECmissing,"missing surface");
1278 LCHECKNT(sim->srfss && sim->srfss->nsrf,funcname,ECnonexist,"no surfaces defined");
1279 LCHECKNT(strcmp(surface,"all"),funcname,ECall,"surface cannot be 'all'");
1280 s=stringfind(sim->srfss->snames,sim->srfss->nsrf,surface);
1281 LCHECKNT(s>=0,funcname,ECnonexist,"surface not found");
1282 return s;
1283 failure:
1284 return (int)Liberrorcode; }
1285
1286
1287 /* smolGetSurfaceName */
smolGetSurfaceName(simptr sim,int surfaceindex,char * surface)1288 extern CSTRING char *smolGetSurfaceName(simptr sim,int surfaceindex,char *surface) {
1289 const char *funcname="smolGetSurfaceName";
1290
1291 LCHECK(sim,funcname,ECmissing,"missing sim");
1292 LCHECK(surfaceindex>=0,funcname,ECbounds,"invalid surface index");
1293 LCHECK(surface,funcname,ECmissing,"missing surface");
1294 LCHECK(sim->srfss && sim->srfss->nsrf,funcname,ECnonexist,"no surfaces defined");
1295 LCHECK(surfaceindex<sim->srfss->nsrf,funcname,ECnonexist,"surface does not exist");
1296 strcpy(surface,sim->srfss->snames[surfaceindex]);
1297 return surface;
1298 failure:
1299 return NULL; }
1300
1301
1302 /* smolSetSurfaceAction */
smolSetSurfaceAction(simptr sim,const char * surface,enum PanelFace face,const char * species,enum MolecState state,enum SrfAction action,const char * newspecies)1303 extern CSTRING enum ErrorCode smolSetSurfaceAction(simptr sim,const char *surface,enum PanelFace face,const char *species,enum MolecState state,enum SrfAction action,const char *newspecies) {
1304 const char *funcname="smolSetSurfaceAction";
1305 int er,i,s,i2;
1306 surfaceptr srf;
1307
1308 LCHECK(sim,funcname,ECmissing,"missing sim");
1309 s=smolGetSurfaceIndexNT(sim,surface);
1310 if(s==(int)ECall) {smolClearError();s=-5;}
1311 else LCHECK(s>=0,funcname,ECsame,NULL);
1312 LCHECK(face==PFfront || face==PFback || face==PFboth,funcname,ECbounds,"invalid face");
1313 i=smolGetSpeciesIndexNT(sim,species);
1314 if(i==(int)ECall) {smolClearError();i=-5;}
1315 else LCHECK(i>0,funcname,ECsame,NULL);
1316 LCHECK((state>=0 && state<MSMAX) || state==MSall,funcname,ECbounds,"invalid state");
1317 LCHECK(action>=0 && action<=SAmult,funcname,ECbounds,"invalid action");
1318 if(newspecies && strlen(newspecies) > 0) {
1319 i2=smolGetSpeciesIndexNT(sim,newspecies);
1320 LCHECK(i2>0,funcname,ECnonexist,"unrecognized new species name"); }
1321 else
1322 i2=0;
1323 if(s>=0) {
1324 srf=sim->srfss->srflist[s];
1325 er=surfsetaction(srf,i,NULL,state,face,action,0);
1326 LCHECK(!er,funcname,ECbug,"bug in surfsetaction"); }
1327 else {
1328 for(s=0;s<sim->srfss->nsrf;s++) {
1329 srf=sim->srfss->srflist[s];
1330 er=surfsetaction(srf,i,NULL,state,face,action,0);
1331 LCHECK(!er,funcname,ECbug,"bug in surfsetaction"); }}
1332 return ECok;
1333 failure:
1334 return Liberrorcode; }
1335
1336
1337 /* smolSetSurfaceRate */
smolSetSurfaceRate(simptr sim,const char * surface,const char * species,enum MolecState state,enum MolecState state1,enum MolecState state2,double rate,const char * newspecies,int isinternal)1338 extern CSTRING enum ErrorCode smolSetSurfaceRate(simptr sim,const char *surface,const char *species,enum MolecState state,enum MolecState state1,enum MolecState state2,double rate,const char *newspecies,int isinternal) {
1339 const char *funcname="smolSetSurfaceRate";
1340 int er,i,i2,s;
1341 surfaceptr srf;
1342
1343 LCHECK(sim,funcname,ECmissing,"missing sim");
1344 s=smolGetSurfaceIndexNT(sim,surface);
1345 if(s==(int)ECall) {smolClearError();s=-5;}
1346 else LCHECK(s>=0,funcname,ECsame,NULL);
1347 i=smolGetSpeciesIndexNT(sim,species);
1348 if(i==(int)ECall) {smolClearError();i=-5;}
1349 else LCHECK(i>0,funcname,ECsame,NULL);
1350 LCHECK(state>=0 && state<MSMAX,funcname,ECbounds,"invalid state");
1351 LCHECK(state1>=0 && state1<MSMAX1,funcname,ECbounds,"invalid state1");
1352 LCHECK(state==MSsoln || state1==MSsoln || state1==MSbsoln || state1==state,funcname,ECsyntax,"nonsensical state combination");
1353 LCHECK(state2>=0 && state2<MSMAX1,funcname,ECbounds,"invalid state2");
1354 LCHECK(state1!=state2,funcname,ECsyntax,"cannot set rate for state1 = state2");
1355 if(newspecies && newspecies[0]!='\0') {
1356 i2=smolGetSpeciesIndexNT(sim,newspecies);
1357 LCHECK(i2>0,funcname,ECerror,"invalid newspecies"); }
1358 else i2=-5;
1359 LCHECK(rate>=0,funcname,ECbounds,"rate needs to be non-negative");
1360 LCHECK(!(isinternal && rate>1),funcname,ECbounds,"internal rate needs to be <= 1");
1361
1362 if(s>=0) {
1363 srf=sim->srfss->srflist[s];
1364 er=surfsetrate(srf,i,NULL,state,state1,state2,i2,rate,isinternal?2:1);
1365 LCHECK(!er,funcname,ECerror,"error in surfsetrate"); }
1366 else {
1367 for(s=0;s<sim->srfss->nsrf;s++) {
1368 srf=sim->srfss->srflist[s];
1369 er=surfsetrate(srf,i,NULL,state,state1,state2,i2,rate,isinternal?2:1);
1370 LCHECK(!er,funcname,ECerror,"error in surfsetrate"); }}
1371 return ECok;
1372 failure:
1373 return Liberrorcode; }
1374
1375
1376 /* smolAddPanel */
smolAddPanel(simptr sim,const char * surface,enum PanelShape panelshape,const char * panel,const char * axisstring,double * params)1377 extern CSTRING enum ErrorCode smolAddPanel(simptr sim,const char *surface,enum PanelShape panelshape,const char *panel,const char *axisstring,double *params) {
1378 const char *funcname="smolAddPanel";
1379 int er,s;
1380 surfaceptr srf;
1381
1382 LCHECK(sim,funcname,ECmissing,"missing sim");
1383 s=smolGetSurfaceIndexNT(sim,surface);
1384 LCHECK(s>=0,funcname,ECsame,NULL);
1385 LCHECK(panelshape>=0 && panelshape<PSMAX,funcname,ECnonexist,"invalid panel shape");
1386 if(panelshape==PSrect) {
1387 LCHECK(axisstring,funcname,ECmissing,"missing axisstring"); }
1388 LCHECK(params,funcname,ECmissing,"missing params");
1389 srf=sim->srfss->srflist[s];
1390 er=surfaddpanel(srf,sim->dim,panelshape,axisstring,params,panel);
1391 LCHECK(er!=-1,funcname,ECmemory,"out of memory adding panel");
1392 LCHECK(er!=3,funcname,ECsyntax,"cannot parse axisstring");
1393 LCHECK(er!=4,funcname,ECbounds,"drawing slices and stacks need to be positive");
1394 LCHECK(er!=5,funcname,ECbounds,"cylinder ends cannot be at the same location");
1395 LCHECK(er!=6,funcname,ECbounds,"hemisphere outward pointing vector has zero length");
1396 LCHECK(er!=7,funcname,ECbounds,"radius needs to be positive");
1397 LCHECK(er!=8,funcname,ECbounds,"normal vector has zero length");
1398 LCHECK(er!=9,funcname,ECerror,"panel name was used before for a different panel shape");
1399 LCHECK(!er,funcname,ECbug,"bug in smolAddPanel");
1400 return ECok;
1401 failure:
1402 return Liberrorcode; }
1403
1404
1405 /* smolGetPanelIndex */
smolGetPanelIndex(simptr sim,const char * surface,enum PanelShape * panelshapeptr,const char * panel)1406 extern CSTRING int smolGetPanelIndex(simptr sim,const char *surface,enum PanelShape *panelshapeptr,const char *panel) {
1407 const char *funcname="smolGetPanelIndex";
1408 surfaceptr srf;
1409 int p,s;
1410 enum PanelShape ps;
1411
1412 LCHECK(sim,funcname,ECmissing,"missing sim");
1413 s=smolGetSurfaceIndexNT(sim,surface);
1414 LCHECK(s>=0,funcname,ECsame,NULL);
1415 LCHECK(panel,funcname,ECmissing,"missing panel name");
1416 LCHECK(strcmp(panel,"all"),funcname,ECall,"panel cannot be 'all'");
1417 srf=sim->srfss->srflist[s];
1418 p=-1;
1419
1420 #if 0
1421 for(ps=(enum PanelShape)0;ps<(enum PanelShape)PSMAX && p<0;ps=(enum PanelShape)(ps+1))
1422 p=stringfind(srf->pname[ps],srf->npanel[ps],panel);
1423 #else
1424 for(auto ips : AllPanels_arr) {
1425 int _ips = static_cast<int>(ips);
1426 p = stringfind(srf->pname[_ips], srf->npanel[_ips], panel);
1427 if(p >= 0) {
1428 ps = ips;
1429 break;
1430 }
1431 }
1432 #endif
1433
1434 LCHECK(p>=0,funcname,ECnonexist,"panel not found");
1435 if(panelshapeptr) *panelshapeptr=ps;
1436 return p;
1437 failure:
1438 return (int)Liberrorcode; }
1439
1440
1441 /* smolGetPanelIndexNT */
smolGetPanelIndexNT(simptr sim,const char * surface,enum PanelShape * panelshapeptr,const char * panel)1442 extern CSTRING int smolGetPanelIndexNT(simptr sim,const char *surface,enum PanelShape *panelshapeptr,const char *panel) {
1443 const char *funcname="smolGetPanelIndexNT";
1444 surfaceptr srf;
1445 int p,s;
1446 enum PanelShape ps;
1447
1448 LCHECKNT(sim,funcname,ECmissing,"missing sim");
1449 s=smolGetSurfaceIndexNT(sim,surface);
1450 LCHECKNT(s>=0,funcname,ECsame,NULL);
1451 LCHECKNT(panel,funcname,ECmissing,"missing panel name");
1452 LCHECKNT(strcmp(panel,"all"),funcname,ECall,"panel cannot be 'all'");
1453 srf=sim->srfss->srflist[s];
1454 p=-1;
1455 #if 0
1456 for(ps=(enum PanelShape)0;ps<(enum PanelShape)PSMAX && p<0;ps=(enum PanelShape)(ps+1))
1457 p=stringfind(srf->pname[ps],srf->npanel[ps],panel);
1458 #else
1459 for(auto ips : AllPanels_arr) {
1460 int _ips = static_cast<int>(ips);
1461 p = stringfind(srf->pname[_ips], srf->npanel[_ips], panel);
1462 if(p >= 0) {
1463 ps = ips;
1464 break;
1465 }
1466 }
1467 #endif
1468 LCHECKNT(p>=0,funcname,ECnonexist,"panel not found");
1469 if(panelshapeptr) *panelshapeptr=ps;
1470 return p;
1471 failure:
1472 return (int)Liberrorcode; }
1473
1474
1475 /* smolGetPanelName */
smolGetPanelName(simptr sim,const char * surface,enum PanelShape panelshape,int panelindex,char * panel)1476 extern CSTRING char *smolGetPanelName(simptr sim,const char *surface,enum PanelShape panelshape,int panelindex,char *panel) {
1477 const char *funcname="smolGetPanelName";
1478 surfaceptr srf;
1479 int s;
1480
1481 LCHECK(sim,funcname,ECmissing,"missing sim");
1482 s=smolGetSurfaceIndexNT(sim,surface);
1483 LCHECK(s>=0,funcname,ECsame,NULL);
1484 LCHECK(panelshape>=0 && panelshape<PSMAX,funcname,ECnonexist,"invalid panel shape");
1485 LCHECK(panelindex>=0,funcname,ECbounds,"invalid panel index");
1486 LCHECK(panel,funcname,ECmissing,"missing panel name");
1487 srf=sim->srfss->srflist[s];
1488 LCHECK(panelindex<srf->npanel[panelshape],funcname,ECnonexist,"no panel exists with this number");
1489 strcpy(panel,srf->pname[panelshape][panelindex]);
1490 return panel;
1491 failure:
1492 return NULL; }
1493
1494
1495 /* smolSetPanelJump */
smolSetPanelJump(simptr sim,const char * surface,const char * panel1,enum PanelFace face1,const char * panel2,enum PanelFace face2,int isbidirectional)1496 extern CSTRING enum ErrorCode smolSetPanelJump(simptr sim,const char *surface,const char *panel1,enum PanelFace face1,const char *panel2,enum PanelFace face2,int isbidirectional) {
1497 const char *funcname="smolSetPanelJump";
1498 int s,p1,p2,er;
1499 surfaceptr srf;
1500 enum PanelShape ps1,ps2;
1501 panelptr pnl1,pnl2;
1502
1503 LCHECK(sim,funcname,ECmissing,"missing sim");
1504 s=smolGetSurfaceIndexNT(sim,surface);
1505 LCHECK(s>=0,funcname,ECsame,NULL);
1506 p1=smolGetPanelIndexNT(sim,surface,&ps1,panel1);
1507 LCHECK(p1>=0,funcname,ECsame,NULL);
1508 p2=smolGetPanelIndexNT(sim,surface,&ps2,panel2);
1509 LCHECK(p2>=0,funcname,ECsame,NULL);
1510 LCHECK(ps1==ps2,funcname,ECerror,"origin and destination jump panels need to have the same shape");
1511 LCHECK(p1!=p2,funcname,ECerror,"origin and destination jump panels cannot be the same panel");
1512 LCHECK(face1==PFfront || face1==PFback,funcname,ECsyntax,"jumping panel face has to be either front or back");
1513 LCHECK(face2==PFfront || face2==PFback,funcname,ECsyntax,"jumping panel face has to be either front or back");
1514 LCHECK(isbidirectional==0 || isbidirectional==1,funcname,ECsyntax,"bidirectional code has to be 0 or 1");
1515
1516 srf=sim->srfss->srflist[s];
1517 pnl1=srf->panels[ps1][p1];
1518 pnl2=srf->panels[ps2][p2];
1519 er=surfsetjumppanel(srf,pnl1,face1,isbidirectional,pnl2,face2);
1520 LCHECK(!er,funcname,ECbug,"BUG: error code returned by surfsetjumppanel");
1521 return ECok;
1522 failure:
1523 return Liberrorcode; }
1524
1525
1526 /* smolAddSurfaceUnboundedEmitter */
smolAddSurfaceUnboundedEmitter(simptr sim,const char * surface,enum PanelFace face,const char * species,double emitamount,double * emitposition)1527 extern CSTRING enum ErrorCode smolAddSurfaceUnboundedEmitter(simptr sim,const char *surface,enum PanelFace face,const char *species,double emitamount,double *emitposition) {
1528 const char *funcname="smolAddSurfaceUnboundedEmitter";
1529 int s,i,er;
1530 surfaceptr srf;
1531
1532 LCHECK(sim,funcname,ECmissing,"missing sim");
1533 s=smolGetSurfaceIndexNT(sim,surface);
1534 LCHECK(s>=0,funcname,ECsame,NULL);
1535 LCHECK(face==PFfront || face==PFback,funcname,ECsyntax,"jumping panel face has to be either front or back");
1536 i=smolGetSpeciesIndexNT(sim,species);
1537 LCHECK(i>0,funcname,ECsame,NULL);
1538
1539 srf=sim->srfss->srflist[s];
1540 er=surfaddemitter(srf,face,i,emitamount,emitposition,sim->dim);
1541 LCHECK(!er,funcname,ECmemory,"out of memory allocating unbounded emitter");
1542
1543 return ECok;
1544 failure:
1545 return Liberrorcode; }
1546
1547
1548 /* smolSetSurfaceSimParams */
smolSetSurfaceSimParams(simptr sim,const char * parameter,double value)1549 extern CSTRING enum ErrorCode smolSetSurfaceSimParams(simptr sim,const char *parameter,double value) {
1550 const char *funcname="smolSetSurfaceSimParams";
1551 int er;
1552
1553 LCHECK(sim,funcname,ECmissing,"missing sim");
1554 LCHECK(parameter,funcname,ECmissing,"missing parameter name");
1555 if(!strcmp(parameter,"epsilon")) {
1556 er=surfsetepsilon(sim,value);
1557 LCHECK(er!=2,funcname,ECmemory,"out of memory enabling surfaces");
1558 LCHECK(er!=3,funcname,ECbounds,"epsilon needs to be >0"); }
1559 else if(!strcmp(parameter,"margin")) {
1560 er=surfsetmargin(sim,value);
1561 LCHECK(er!=2,funcname,ECmemory,"out of memory enabling surfaces");
1562 LCHECK(er!=3,funcname,ECbounds,"margin needs to be >=0"); }
1563 else if(!strcmp(parameter,"neighbordist")) {
1564 er=surfsetneighdist(sim,value);
1565 LCHECK(er!=2,funcname,ECmemory,"out of memory enabling surfaces");
1566 LCHECK(er!=3,funcname,ECbounds,"neighbor distance needs to be >0"); }
1567 else
1568 LCHECK(0,funcname,ECsyntax,"parameter name not recognized");
1569
1570 return ECok;
1571 failure:
1572 return Liberrorcode; }
1573
1574
1575 /* smolAddPanelNeighbor */
smolAddPanelNeighbor(simptr sim,const char * surface1,const char * panel1,const char * surface2,const char * panel2,int reciprocal)1576 extern CSTRING enum ErrorCode smolAddPanelNeighbor(simptr sim,const char *surface1,const char *panel1,const char *surface2,const char *panel2,int reciprocal) {
1577 const char *funcname="smolAddPanelNeighbor";
1578 int s1,s2,p1,p2,er;
1579 panelptr pnl1,pnl2;
1580 enum PanelShape ps1,ps2;
1581
1582 LCHECK(sim,funcname,ECmissing,"missing sim");
1583 s1=smolGetSurfaceIndexNT(sim,surface1);
1584 LCHECK(s1>=0,funcname,ECsame,NULL);
1585 s2=smolGetSurfaceIndexNT(sim,surface2);
1586 LCHECK(s2>=0,funcname,ECsame,NULL);
1587 p1=smolGetPanelIndexNT(sim,surface1,&ps1,panel1);
1588 LCHECK(p1>=0,funcname,ECsame,NULL);
1589 p2=smolGetPanelIndexNT(sim,surface2,&ps2,panel2);
1590 LCHECK(p2>=0,funcname,ECsame,NULL);
1591 LCHECK(!(s1==s2 && p1==p2 && ps1 == ps2),funcname,ECerror,"panels cannot be their own neighbors");
1592
1593 pnl1=sim->srfss->srflist[s1]->panels[ps1][p1];
1594 pnl2=sim->srfss->srflist[s2]->panels[ps2][p2];
1595 er=surfsetneighbors(pnl1,&pnl2,1,1);
1596 LCHECK(!er,funcname,ECmemory,"out of memory adding panel neighbor");
1597 if(reciprocal) {
1598 er=surfsetneighbors(pnl2,&pnl1,1,1);
1599 LCHECK(!er,funcname,ECmemory,"out of memory adding panel neighbor"); }
1600
1601 return ECok;
1602 failure:
1603 return Liberrorcode; }
1604
1605
1606 /* smolSetSurfaceStyle */
smolSetSurfaceStyle(simptr sim,const char * surface,enum PanelFace face,enum DrawMode mode,double thickness,double * color,int stipplefactor,int stipplepattern,double shininess)1607 extern CSTRING enum ErrorCode smolSetSurfaceStyle(simptr sim,const char *surface,enum PanelFace face,enum DrawMode mode,double thickness,double *color,int stipplefactor,int stipplepattern,double shininess) {
1608 const char *funcname="smolSetSurfaceFaceStyle";
1609 int s,c,er;
1610 surfaceptr srf;
1611
1612 LCHECK(sim,funcname,ECmissing,"missing sim");
1613 s=smolGetSurfaceIndexNT(sim,surface);
1614 if(s==(int)ECall) {smolClearError();s=-5;}
1615 else LCHECK(s>=0,funcname,ECsame,NULL);
1616 srf=sim->srfss->srflist[s];
1617
1618 if(mode!=DMnone) {
1619 LCHECK(mode>=0 && mode<DMnone,funcname,ECsyntax,"mode not recognized");
1620 er=surfsetdrawmode(srf,face,mode);
1621 LCHECK(!er,funcname,ECbug,"BUG: error in surfsetdrawmode"); }
1622 if(thickness>=0) {
1623 er=surfsetedgepts(srf,thickness);
1624 LCHECK(!er,funcname,ECbug,"BUG: error in surfsetedgepts"); }
1625 if(color) {
1626 for(c=0;c<4;c++)
1627 LCHECK(color[c]>=0 && color[c]<=1,funcname,ECbounds,"color value out of bounds");
1628 er=surfsetcolor(srf,face,color);
1629 LCHECK(!er,funcname,ECbug,"BUG: error in surfsetcolor"); }
1630 if(stipplefactor>=0) {
1631 LCHECK(stipplefactor>0,funcname,ECbounds,"stipplefactor needs to be >0");
1632 er=surfsetstipple(srf,stipplefactor,-1);
1633 LCHECK(!er,funcname,ECbug,"BUG: error in surfsetstipple"); }
1634 if(stipplepattern>=0) {
1635 LCHECK(stipplepattern<=0xFFFF,funcname,ECbounds,"stipplepattern needs to be between 0 and 0xFFFF");
1636 er=surfsetstipple(srf,-1,stipplepattern);
1637 LCHECK(!er,funcname,ECbug,"BUG: error in surfsetstipple"); }
1638 if(shininess>=0) {
1639 LCHECK(shininess<=128,funcname,ECbounds,"shininess cannot exceed 128");
1640 er=surfsetshiny(srf,face,shininess);
1641 LCHECK(!er,funcname,ECbug,"BUG: error in surfsetshiny"); }
1642
1643 return ECok;
1644 failure:
1645 return Liberrorcode; }
1646
1647
1648 /******************************************************************************/
1649 /******************************** Compartments ********************************/
1650 /******************************************************************************/
1651
1652 /* smolAddCompartment */
smolAddCompartment(simptr sim,const char * compartment)1653 extern CSTRING enum ErrorCode smolAddCompartment(simptr sim,const char *compartment) {
1654 const char *funcname="smolAddCompartment";
1655 int c;
1656 compartptr cmpt;
1657
1658 LCHECK(sim,funcname,ECmissing,"missing sim");
1659 c=smolGetCompartmentIndexNT(sim,compartment);
1660 if(c==(int)ECnonexist) smolClearError();
1661 else if(c<0) LCHECK(0,funcname,ECsame,NULL);
1662 else LCHECK(0,funcname,ECerror,"compartment is already in system");
1663 cmpt=compartaddcompart(sim,compartment);
1664 LCHECK(cmpt,funcname,ECmemory,"out of memory adding compartment");
1665 return ECok;
1666 failure:
1667 return Liberrorcode; }
1668
1669
1670 /* smolGetCompartmentIndex */
smolGetCompartmentIndex(simptr sim,const char * compartment)1671 extern CSTRING int smolGetCompartmentIndex(simptr sim,const char *compartment) {
1672 const char *funcname="smolGetCompartmentIndex";
1673 int c;
1674
1675 LCHECK(sim,funcname,ECmissing,"missing sim");
1676 LCHECK(compartment,funcname,ECmissing,"missing compartment");
1677 LCHECK(sim->cmptss && sim->cmptss->ncmpt,funcname,ECnonexist,"no compartments defined");
1678 LCHECK(strcmp(compartment,"all"),funcname,ECall,"compartment cannot be 'all'");
1679 c=stringfind(sim->cmptss->cnames,sim->cmptss->ncmpt,compartment);
1680 LCHECK(c>=0,funcname,ECnonexist,"compartment not found");
1681 return c;
1682 failure:
1683 return (int)Liberrorcode; }
1684
1685
1686 /* smolGetCompartmentIndexNT */
smolGetCompartmentIndexNT(simptr sim,const char * compartment)1687 extern CSTRING int smolGetCompartmentIndexNT(simptr sim,const char *compartment) {
1688 const char *funcname="smolGetCompartmentIndexNT";
1689 int c;
1690
1691 LCHECKNT(sim,funcname,ECmissing,"missing sim");
1692 LCHECKNT(compartment,funcname,ECmissing,"missing compartment");
1693 LCHECKNT(sim->cmptss && sim->cmptss->ncmpt,funcname,ECnonexist,"no compartments defined");
1694 LCHECKNT(strcmp(compartment,"all"),funcname,ECall,"compartment cannot be 'all'");
1695 c=stringfind(sim->cmptss->cnames,sim->cmptss->ncmpt,compartment);
1696 LCHECKNT(c>=0,funcname,ECnonexist,"compartment not found");
1697 return c;
1698 failure:
1699 return (int)Liberrorcode; }
1700
1701
1702 /* smolGetCompartmentName */
smolGetCompartmentName(simptr sim,int compartmentindex,char * compartment)1703 extern CSTRING char *smolGetCompartmentName(simptr sim,int compartmentindex,char *compartment) {
1704 const char *funcname="smolGetCompartmentName";
1705
1706 LCHECK(sim,funcname,ECmissing,"missing sim");
1707 LCHECK(compartmentindex>=0,funcname,ECbounds,"invalid compartment index");
1708 LCHECK(compartment,funcname,ECmissing,"missing compartment string");
1709 LCHECK(sim->cmptss && sim->cmptss->ncmpt,funcname,ECnonexist,"no compartments defined");
1710 LCHECK(compartmentindex<sim->cmptss->ncmpt,funcname,ECnonexist,"compartment does not exist");
1711 strcpy(compartment,sim->cmptss->cnames[compartmentindex]);
1712 return compartment;
1713 failure:
1714 return NULL; }
1715
1716
1717 /* smolAddCompartmentSurface */
smolAddCompartmentSurface(simptr sim,const char * compartment,const char * surface)1718 extern CSTRING enum ErrorCode smolAddCompartmentSurface(simptr sim,const char *compartment,const char *surface) {
1719 const char *funcname="smolAddCompartmentSurface";
1720 int c,s,er;
1721
1722 LCHECK(sim,funcname,ECmissing,"missing sim");
1723 c=smolGetCompartmentIndexNT(sim,compartment);
1724 LCHECK(c>=0,funcname,ECsame,NULL);
1725 s=smolGetSurfaceIndexNT(sim,surface);
1726 LCHECK(s>=0,funcname,ECsame,NULL);
1727 er=compartaddsurf(sim->cmptss->cmptlist[c],sim->srfss->srflist[s]);
1728 LCHECK(!er,funcname,ECmemory,"out of memory in compartaddsurf");
1729 return ECok;
1730 failure:
1731 return Liberrorcode; }
1732
1733
1734 /* smolAddCompartmentPoint */
smolAddCompartmentPoint(simptr sim,const char * compartment,double * point)1735 extern CSTRING enum ErrorCode smolAddCompartmentPoint(simptr sim,const char *compartment,double *point) {
1736 const char *funcname="smolAddCompartmentPoint";
1737 int c,er;
1738
1739 LCHECK(sim,funcname,ECmissing,"missing sim");
1740 c=smolGetCompartmentIndexNT(sim,compartment);
1741 LCHECK(c>=0,funcname,ECsame,NULL);
1742 LCHECK(point,funcname,ECmissing,"missing point");
1743 er=compartaddpoint(sim->cmptss->cmptlist[c],sim->dim,point);
1744 LCHECK(!er,funcname,ECmemory,"out of memory in compartaddsurf");
1745 return ECok;
1746 failure:
1747 return Liberrorcode; }
1748
1749
1750 /* smolAddCompartmentLogic */
smolAddCompartmentLogic(simptr sim,const char * compartment,enum CmptLogic logic,const char * compartment2)1751 extern CSTRING enum ErrorCode smolAddCompartmentLogic(simptr sim,const char *compartment,enum CmptLogic logic,const char *compartment2) {
1752 const char *funcname="smolAddCompartmentLogic";
1753 int c,c2,er;
1754
1755 LCHECK(sim,funcname,ECmissing,"missing sim");
1756 c=smolGetCompartmentIndexNT(sim,compartment);
1757 LCHECK(c>=0,funcname,ECsame,NULL);
1758 LCHECK(logic>=CLequal && logic<CLnone,funcname,ECsyntax,"invalid logic operation");
1759 c2=smolGetCompartmentIndexNT(sim,compartment2);
1760 LCHECK(c2>=0,funcname,ECerror,"error with compartment2");
1761 er=compartaddcmptl(sim->cmptss->cmptlist[c],sim->cmptss->cmptlist[c2],logic);
1762 LCHECK(!er,funcname,ECmemory,"out of memory in compartaddcmpt");
1763 return ECok;
1764 failure:
1765 return Liberrorcode; }
1766
1767
1768
1769 /******************************************************************************/
1770 /********************************* Reactions **********************************/
1771 /******************************************************************************/
1772
1773 /* smolAddReaction */
smolAddReaction(simptr sim,const char * reaction,const char * reactant1,enum MolecState rstate1,const char * reactant2,enum MolecState rstate2,int nproduct,const char ** productspecies,enum MolecState * productstates,double rate)1774 extern CSTRING enum ErrorCode smolAddReaction(simptr sim,const char *reaction,const char *reactant1,enum MolecState rstate1,const char *reactant2,enum MolecState rstate2,int nproduct,const char **productspecies,enum MolecState *productstates,double rate) {
1775 const char *funcname="smolAddReaction";
1776 rxnptr rxn;
1777 int order,prd,rctident[MAXORDER],prdident[MAXPRODUCT],er;
1778 enum MolecState rctstate[MAXORDER];
1779
1780 LCHECK(sim,funcname,ECmissing,"missing sim");
1781 LCHECK(reaction,funcname,ECmissing,"missing reaction name");
1782 order=0;
1783 rctident[0]=rctident[1]=0;
1784 rctstate[0]=rctstate[1]=MSnone;
1785 if(reactant1 && reactant1[0]!='\0') {
1786 rctident[order]=smolGetSpeciesIndexNT(sim,reactant1);
1787 LCHECK(rctident[order]>0,funcname,ECsame,NULL);
1788 LCHECK(rstate1>=0 && rstate1<=MSMAX,funcname,ECbounds,"invalid rstate1");
1789 rctstate[order]=rstate1;
1790 order++; }
1791 if(reactant2 && reactant2[0]!='\0') {
1792 rctident[order]=smolGetSpeciesIndexNT(sim,reactant2);
1793 LCHECK(rctident[order]>0,funcname,ECsame,NULL);
1794 LCHECK(rstate2>=0 && rstate2<=MSMAX,funcname,ECbounds,"invalid rstate2");
1795 rctstate[order]=rstate2;
1796 order++; }
1797 LCHECK(nproduct>=0,funcname,ECbounds,"invalid nproduct");
1798 if(nproduct) {
1799 LCHECK(productspecies,funcname,ECmissing,"missing product species");
1800 LCHECK(productstates,funcname,ECmissing,"missing product states");
1801 for(prd=0;prd<nproduct;prd++) {
1802 prdident[prd]=smolGetSpeciesIndexNT(sim,productspecies[prd]);
1803 LCHECK(prdident[prd]>0,funcname,ECsame,NULL);
1804 LCHECK(productstates[prd]>=MSsoln && productstates[prd]<=MSMAX,funcname,ECsyntax,"invalid product state"); }}
1805 rxn=RxnAddReaction(sim,reaction,order,rctident,rctstate,nproduct,prdident,productstates,NULL,NULL);
1806 LCHECK(rxn,funcname,ECmemory,"out of memory allocating reaction");
1807
1808 if(rate>=0) {
1809 er=RxnSetValue(sim,"rate",rxn,rate);
1810 if(er==3) LCHECK(0,funcname,ECwarning,"rate was set previously");
1811 else LCHECK(!er,funcname,ECbug,"RxnSetValue error"); }
1812
1813 return Libwarncode;
1814 failure:
1815 return Liberrorcode; }
1816
1817
1818 /* smolGetReactionIndex */
smolGetReactionIndex(simptr sim,int * orderptr,const char * reaction)1819 extern CSTRING int smolGetReactionIndex(simptr sim,int *orderptr,const char *reaction) {
1820 const char *funcname="smolGetReactionIndex";
1821 int order,r;
1822
1823 LCHECK(sim,funcname,ECmissing,"missing sim");
1824 LCHECK(reaction,funcname,ECmissing,"missing reaction");
1825 LCHECK(strcmp(reaction,"all"),funcname,ECall,"reaction cannot be 'all'");
1826 if(orderptr && *orderptr>=0 && *orderptr<MAXORDER) {
1827 order=*orderptr;
1828 LCHECK(sim->rxnss[order] && sim->rxnss[order]->totrxn,funcname,ECnonexist,"no reactions defined of this order");
1829 r=stringfind(sim->rxnss[order]->rname,sim->rxnss[order]->totrxn,reaction);
1830 LCHECK(r>=0,funcname,ECnonexist,"reaction not found"); }
1831 else {
1832 r=-1;
1833 for(order=0;order<MAXORDER && r<0;order++)
1834 if(sim->rxnss[order])
1835 r=stringfind(sim->rxnss[order]->rname,sim->rxnss[order]->totrxn,reaction);
1836 LCHECK(r>=0,funcname,ECnonexist,"reaction not found");
1837 if(orderptr) *orderptr=order-1; }
1838 return r;
1839 failure:
1840 return (int)Liberrorcode; }
1841
1842
1843 /* smolGetReactionIndexNT */
smolGetReactionIndexNT(simptr sim,int * orderptr,const char * reaction)1844 extern CSTRING int smolGetReactionIndexNT(simptr sim,int *orderptr,const char *reaction) {
1845 const char *funcname="smolGetReactionIndexNT";
1846 int order,r;
1847
1848 LCHECKNT(sim,funcname,ECmissing,"missing sim");
1849 LCHECKNT(reaction,funcname,ECmissing,"missing reaction");
1850 LCHECKNT(strcmp(reaction,"all"),funcname,ECall,"reaction cannot be 'all'");
1851 if(orderptr && *orderptr>=0 && *orderptr<MAXORDER) {
1852 order=*orderptr;
1853 LCHECKNT(sim->rxnss[order] && sim->rxnss[order]->totrxn,funcname,ECnonexist,"no reactions defined of this order");
1854 r=stringfind(sim->rxnss[order]->rname,sim->rxnss[order]->totrxn,reaction);
1855 LCHECKNT(r>=0,funcname,ECnonexist,"reaction not found"); }
1856 else {
1857 r=-1;
1858 for(order=0;order<MAXORDER && r<0;order++)
1859 if(sim->rxnss[order])
1860 r=stringfind(sim->rxnss[order]->rname,sim->rxnss[order]->totrxn,reaction);
1861 LCHECKNT(r>=0,funcname,ECnonexist,"reaction not found");
1862 if(orderptr) *orderptr=order-1; }
1863 return r;
1864 failure:
1865 return (int)Liberrorcode; }
1866
1867
1868 /* smolGetReactionName */
smolGetReactionName(simptr sim,int order,int reactionindex,char * reaction)1869 extern CSTRING char *smolGetReactionName(simptr sim,int order,int reactionindex,char *reaction) {
1870 const char *funcname="smolGetReactionName";
1871
1872 LCHECK(sim,funcname,ECmissing,"missing sim");
1873 LCHECK(order>=0 && order<MAXORDER,funcname,ECbounds,"invalid reaction order");
1874 LCHECK(reactionindex>=0,funcname,ECbounds,"invalid reaction name");
1875 LCHECK(reaction,funcname,ECmissing,"missing reaction");
1876 LCHECK(sim->rxnss[order] && sim->rxnss[order]->totrxn,funcname,ECnonexist,"no reactions defined of this order");
1877 LCHECK(reactionindex<sim->rxnss[order]->totrxn,funcname,ECnonexist,"reaction does not exist");
1878 strcpy(reaction,sim->rxnss[order]->rname[reactionindex]);
1879 return reaction;
1880 failure:
1881 return NULL; }
1882
1883
1884 /* smolSetReactionRate */
smolSetReactionRate(simptr sim,const char * reaction,double rate,int isinternal)1885 extern CSTRING enum ErrorCode smolSetReactionRate(simptr sim,const char *reaction,double rate,int isinternal) {
1886 const char *funcname="smolSetReactionRate";
1887 int r,er,order;
1888 rxnptr rxn;
1889
1890 LCHECK(sim,funcname,ECmissing,"missing sim");
1891 order=-1;
1892 r=smolGetReactionIndexNT(sim,&order,reaction);
1893 LCHECK(r>=0,funcname,ECsame,NULL);
1894 rxn=sim->rxnss[order]->rxn[r];
1895 if(!isinternal)
1896 er=RxnSetValue(sim,"rate",rxn,rate);
1897 else if(order<2)
1898 er=RxnSetValue(sim,"prob",rxn,rate);
1899 else
1900 er=RxnSetValue(sim,"bindrad",rxn,rate);
1901 if(er==3) LCHECK(0,funcname,ECwarning,"rate was set previously");
1902 else LCHECK(!er,funcname,ECbug,"RxnSetValue error");
1903 return Libwarncode;
1904 failure:
1905 return Liberrorcode; }
1906
1907
1908 /* smolSetReactionRegion */
smolSetReactionRegion(simptr sim,const char * reaction,const char * compartment,const char * surface)1909 extern CSTRING enum ErrorCode smolSetReactionRegion(simptr sim,const char *reaction,const char *compartment,const char *surface) {
1910 const char *funcname="smolSetReactionRegion";
1911 int order,r,c,s;
1912 rxnptr rxn;
1913
1914 LCHECK(sim,funcname,ECmissing,"missing sim");
1915 order=-1;
1916 r=smolGetReactionIndexNT(sim,&order,reaction);
1917 LCHECK(r>=0,funcname,ECsame,NULL);
1918 rxn=sim->rxnss[order]->rxn[r];
1919
1920 if(compartment && compartment[0]!='\0') {
1921 c=smolGetCompartmentIndexNT(sim,compartment);
1922 LCHECK(c>=0,funcname,ECsame,NULL);
1923 RxnSetCmpt(rxn,sim->cmptss->cmptlist[c]); }
1924 else if(compartment && compartment[0]=='\0')
1925 RxnSetCmpt(rxn,NULL);
1926
1927 if(surface && surface[0]!='\0') {
1928 s=smolGetSurfaceIndexNT(sim,surface);
1929 LCHECK(s>=0,funcname,ECsame,NULL);
1930 RxnSetSurface(rxn,sim->srfss->srflist[s]); }
1931 else if(surface && surface[0]=='\0')
1932 RxnSetSurface(rxn,NULL);
1933
1934 return ECok;
1935 failure:
1936 return Liberrorcode; }
1937
1938
1939 /* smolSetReactionIntersurface */
smolSetReactionIntersurface(simptr sim,const char * reaction,int * rulelist)1940 enum ErrorCode smolSetReactionIntersurface(
1941 simptr sim, const char *reaction, int *rulelist)
1942 {
1943 const char *funcname = "smolSetReactionIntersurface";
1944 int order, r, i;
1945 int er;
1946 listptrv vlist;
1947 rxnptr rxn = NULL;
1948
1949 readrxnname(sim, reaction, &order, &rxn, NULL, 1);
1950 if(!rxn)
1951 readrxnname(sim, reaction, &order, &rxn, NULL, 2);
1952 if(!rxn)
1953 readrxnname(sim, reaction, &order, &rxn, NULL, 3);
1954
1955 LCHECK(rxn, funcname, ECnonexist, NULL);
1956 LCHECK(order == 2, funcname, ECerror, NULL);
1957
1958 rxn = NULL;
1959 r = readrxnname(sim, reaction, NULL, &rxn, NULL, 1);
1960 if(r >= 0) {
1961 er = RxnSetIntersurfaceRules(rxn, rulelist);
1962 LCHECK(er != 1, funcname, ECmemory, NULL);
1963 }
1964 r = readrxnname(sim, reaction, NULL, &rxn, &vlist, 2);
1965 LCHECK(r != -2, funcname, ECmemory, NULL);
1966 if(r >= 0) {
1967 for(i = 0; i < vlist->n; i++) {
1968 er = RxnSetIntersurfaceRules((rxnptr)vlist->xs[i], rulelist);
1969 LCHECK(er != 1, funcname, ECmemory, NULL);
1970 }
1971 ListFreeV(vlist);
1972 }
1973 r = readrxnname(sim, reaction, NULL, &rxn, NULL, 3);
1974 LCHECK(r != -2, funcname, ECmemory, NULL);
1975 if(r >= 0) {
1976 er = RxnSetIntersurfaceRules(rxn, rulelist);
1977 LCHECK(er != 1, funcname, ECmemory, NULL);
1978 }
1979
1980 return ECok;
1981 failure:
1982 return Liberrorcode;
1983 }
1984
1985 /* smolSetReactionProducts */
smolSetReactionProducts(simptr sim,const char * reaction,enum RevParam method,double parameter,const char * product,double * position)1986 extern CSTRING enum ErrorCode smolSetReactionProducts(simptr sim,const char *reaction,enum RevParam method,double parameter,const char *product,double *position) {
1987 const char *funcname="smolSetReactionProducts";
1988 int order,r,done,prd,i,er;
1989 rxnptr rxn;
1990
1991 LCHECK(sim,funcname,ECmissing,"missing sim");
1992 order=-1;
1993 r=smolGetReactionIndexNT(sim,&order,reaction);
1994 LCHECK(r>=0,funcname,ECsame,NULL);
1995 rxn=sim->rxnss[order]->rxn[r];
1996
1997 prd=-1;
1998 if(product && strlen(product)>0) {
1999 i=smolGetSpeciesIndexNT(sim,product);
2000 LCHECK(i>0,funcname,ECsame,NULL);
2001 done=0;
2002 for(prd=0;prd<rxn->nprod && !done;prd++)
2003 if(rxn->prdident[prd]==i) done=1;
2004 prd--;
2005 LCHECK(done,funcname,ECerror,"listed product is not a product of the listed reaction"); }
2006
2007 er=RxnSetRevparam(sim,rxn,method,parameter,prd,position,sim->dim);
2008 LCHECK(er!=1,funcname,ECwarning,"reaction product parameter was set before");
2009 LCHECK(er!=2,funcname,ECbounds,"reaction product parameter out of bounds");
2010 LCHECK(er!=3,funcname,ECnonexist,"invalid reaction product method");
2011 LCHECK(er!=4,funcname,ECmissing,"missing product name");
2012 LCHECK(er!=5,funcname,ECmissing,"missing product position");
2013
2014 return Libwarncode;
2015 failure:
2016 return Liberrorcode; }
2017
2018
2019
2020 /******************************************************************************/
2021 /*********************************** Ports ************************************/
2022 /******************************************************************************/
2023
2024 /* smolAddPort */
smolAddPort(simptr sim,const char * port,const char * surface,enum PanelFace face)2025 extern CSTRING enum ErrorCode smolAddPort(simptr sim,const char *port,const char *surface,enum PanelFace face) {
2026 const char *funcname="smolAddPort";
2027 int s;
2028 portptr simport;
2029
2030 LCHECK(sim,funcname,ECmissing,"missing sim");
2031 LCHECK(port,funcname,ECmissing,"missing port");
2032 s=smolGetSurfaceIndexNT(sim,surface);
2033 if(s==(int)ECmissing) smolClearError();
2034 else LCHECK(s>=0,funcname,ECsame,NULL);
2035 LCHECK(face==PFfront || face==PFback || face==PFnone,funcname,ECsyntax,"invalid face");
2036 simport=portaddport(sim,port,sim->srfss->srflist[s],face);
2037 LCHECK(simport,funcname,ECmemory,"out of memory adding port");
2038
2039 return ECok;
2040 failure:
2041 return Liberrorcode; }
2042
2043
2044 /* smolGetPortIndex */
smolGetPortIndex(simptr sim,const char * port)2045 extern CSTRING int smolGetPortIndex(simptr sim,const char *port) {
2046 const char *funcname="smolGetPortIndex";
2047 int p;
2048
2049 LCHECK(sim,funcname,ECmissing,"missing sim");
2050 LCHECK(port,funcname,ECmissing,"missing port");
2051 LCHECK(sim->portss && sim->portss->nport,funcname,ECnonexist,"no ports defined");
2052 LCHECK(strcmp(port,"all"),funcname,ECall,"port cannot be 'all'");
2053 p=stringfind(sim->portss->portnames,sim->portss->nport,port);
2054 LCHECK(p>=0,funcname,ECnonexist,"port not found");
2055 return p;
2056 failure:
2057 return (int)Liberrorcode; }
2058
2059
2060 /* smolGetPortIndexNT */
smolGetPortIndexNT(simptr sim,const char * port)2061 extern CSTRING int smolGetPortIndexNT(simptr sim,const char *port) {
2062 const char *funcname="smolGetPortIndexNT";
2063 int p;
2064
2065 LCHECKNT(sim,funcname,ECmissing,"missing sim");
2066 LCHECKNT(port,funcname,ECmissing,"missing port");
2067 LCHECKNT(sim->portss && sim->portss->nport,funcname,ECnonexist,"no ports defined");
2068 LCHECKNT(strcmp(port,"all"),funcname,ECall,"port cannot be 'all'");
2069 p=stringfind(sim->portss->portnames,sim->portss->nport,port);
2070 LCHECKNT(p>=0,funcname,ECnonexist,"port not found");
2071 return p;
2072 failure:
2073 return (int)Liberrorcode; }
2074
2075
2076 /* smolGetPortName */
smolGetPortName(simptr sim,int portindex,char * port)2077 extern CSTRING char *smolGetPortName(simptr sim,int portindex,char *port) {
2078 const char *funcname="smolGetPortName";
2079
2080 LCHECK(sim,funcname,ECmissing,"missing sim");
2081 LCHECK(portindex>=0,funcname,ECbounds,"invalid port index");
2082 LCHECK(port,funcname,ECmissing,"missing port string");
2083 LCHECK(sim->portss && sim->portss->nport,funcname,ECnonexist,"no ports defined");
2084 LCHECK(portindex<sim->portss->nport,funcname,ECnonexist,"port does not exist");
2085 strcpy(port,sim->portss->portnames[portindex]);
2086 return port;
2087 failure:
2088 return NULL; }
2089
2090
2091 /* smolAddPortMolecules */
smolAddPortMolecules(simptr sim,const char * port,int nmolec,const char * species,double ** positions)2092 extern CSTRING enum ErrorCode smolAddPortMolecules(simptr sim,const char *port,int nmolec,const char *species,double **positions) {
2093 const char *funcname="smolAddPortMolecules";
2094 int prt,i,er;
2095 portptr simport;
2096
2097 LCHECK(sim,funcname,ECmissing,"missing sim");
2098 prt=smolGetPortIndexNT(sim,port);
2099 LCHECK(prt>=0,funcname,ECsame,NULL);
2100 simport=sim->portss->portlist[prt];
2101 if(nmolec==0) return ECok;
2102 LCHECK(nmolec>0,funcname,ECbounds,"nmolec cannot be negative");
2103 i=smolGetSpeciesIndexNT(sim,species);
2104 LCHECK(i>0,funcname,ECsame,NULL);
2105 er=portputmols(sim,simport,nmolec,i,NULL,positions,NULL);
2106 LCHECK(er!=1,funcname,ECmemory,"out of memory");
2107 LCHECK(er!=2,funcname,ECnonexist,"no porting surface defined");
2108 LCHECK(er!=3,funcname,ECnonexist,"no porting face defined");
2109 LCHECK(er!=4,funcname,ECnonexist,"no panels on porting surface");
2110
2111 return ECok;
2112 failure:
2113 return Liberrorcode; }
2114
2115
2116 /* smolGetPortMolecules */
smolGetPortMolecules(simptr sim,const char * port,const char * species,enum MolecState state,int remove)2117 extern CSTRING int smolGetPortMolecules(simptr sim,const char *port,const char *species,enum MolecState state,int remove) {
2118 const char *funcname="smolGetPortMolecules";
2119 int prt,i,num;
2120 portptr simport;
2121
2122 LCHECK(sim,funcname,ECmissing,"missing sim");
2123 prt=smolGetPortIndexNT(sim,port);
2124 LCHECK(prt>=0,funcname,ECsame,NULL);
2125 simport=sim->portss->portlist[prt];
2126
2127 i=smolGetSpeciesIndexNT(sim,species);
2128 if(i==(int)ECall) {smolClearError();i=-5;}
2129 else LCHECK(i>0,funcname,ECsame,NULL);
2130 LCHECK((state>=0 && state<MSMAX) || state==MSall,funcname,ECsyntax,"invalid state");
2131
2132 num=portgetmols(sim,simport,i,state,remove);
2133 return num;
2134 failure:
2135 return (int)Liberrorcode; }
2136
2137
2138
2139 /******************************************************************************/
2140 /*********************************** Lattices *********************************/
2141 /******************************************************************************/
2142
2143 /* smolAddLattice */
smolAddLattice(simptr sim,const char * lattice,const double * min,const double * max,const double * dx,const char * btype)2144 extern CSTRING enum ErrorCode smolAddLattice(simptr sim,const char *lattice,const double *min,const double *max,const double *dx,const char *btype) {
2145 const char *funcname="smolAddLattice";
2146 int er,p;
2147 latticeptr simlattice;
2148 simlattice = NULL;
2149 LCHECK(sim,funcname,ECmissing,"missing sim");
2150 LCHECK(lattice,funcname,ECmissing,"missing lattice");
2151 p=stringfind(sim->latticess->latticenames,sim->latticess->nlattice,lattice);
2152 LCHECK(p<0,funcname,ECsame,"lattice name already exists");
2153 er=latticeaddlattice(sim,&simlattice,lattice,min,max,dx,btype,LATTICEnsv);
2154 LCHECK(er==0,funcname,ECerror,"error adding lattice");
2155 LCHECK(simlattice,funcname,ECmemory,"out of memory adding lattice");
2156 return ECok;
2157 failure:
2158 return Liberrorcode;
2159 }
2160
2161
2162 /* smolGetLatticeIndex */
smolGetLatticeIndex(simptr sim,const char * lattice)2163 extern CSTRING int smolGetLatticeIndex(simptr sim,const char *lattice) {
2164 const char *funcname="smolGetLatticeIndex";
2165 int p;
2166
2167 LCHECK(sim,funcname,ECmissing,"missing sim");
2168 LCHECK(lattice,funcname,ECmissing,"missing lattice");
2169 LCHECK(sim->latticess && sim->latticess->nlattice,funcname,ECnonexist,"no lattices defined");
2170 LCHECK(strcmp(lattice,"all"),funcname,ECall,"lattice cannot be 'all'");
2171 p=stringfind(sim->latticess->latticenames,sim->latticess->nlattice,lattice);
2172 LCHECK(p>=0,funcname,ECnonexist,"lattice not found");
2173 return p;
2174 failure:
2175 return (int)Liberrorcode; }
2176
2177
2178 /* smolGetLatticeIndexNT */
smolGetLatticeIndexNT(simptr sim,const char * lattice)2179 extern CSTRING int smolGetLatticeIndexNT(simptr sim,const char *lattice) {
2180 const char *funcname="smolGetLatticeIndexNT";
2181 int p;
2182
2183 LCHECKNT(sim,funcname,ECmissing,"missing sim");
2184 LCHECKNT(lattice,funcname,ECmissing,"missing lattice");
2185 LCHECKNT(sim->latticess && sim->latticess->nlattice,funcname,ECnonexist,"no lattices defined");
2186 LCHECKNT(strcmp(lattice,"all"),funcname,ECall,"lattice cannot be 'all'");
2187 p=stringfind(sim->latticess->latticenames,sim->latticess->nlattice,lattice);
2188 LCHECKNT(p>=0,funcname,ECnonexist,"lattice not found");
2189 return p;
2190 failure:
2191 return (int)Liberrorcode; }
2192
2193
2194 /* smolGetLatticeName */
smolGetLatticeName(simptr sim,int latticeindex,char * lattice)2195 extern CSTRING char *smolGetLatticeName(simptr sim,int latticeindex,char *lattice) {
2196 const char *funcname="smolGetLatticeName";
2197
2198 LCHECK(sim,funcname,ECmissing,"missing sim");
2199 LCHECK(latticeindex>=0,funcname,ECbounds,"invalid lattice index");
2200 LCHECK(lattice,funcname,ECmissing,"missing lattice string");
2201 LCHECK(sim->latticess && sim->latticess->nlattice,funcname,ECnonexist,"no lattices defined");
2202 LCHECK(latticeindex<sim->latticess->nlattice,funcname,ECnonexist,"lattice does not exist");
2203 strcpy(lattice,sim->latticess->latticenames[latticeindex]);
2204 return lattice;
2205 failure:
2206 return NULL; }
2207
2208 /* smolAddLatticeMolecules */
smolAddLatticeMolecules(simptr sim,const char * lattice,const char * species,int number,double * lowposition,double * highposition)2209 extern CSTRING enum ErrorCode smolAddLatticeMolecules(simptr sim,const char *lattice, const char *species,int number,double *lowposition,double *highposition) {
2210 const char *funcname="smolAddLatticeMolecules";
2211 int er,i,lat;
2212 double *low,*high;
2213 latticeptr simlattice;
2214
2215 LCHECK(sim,funcname,ECmissing,"missing sim");
2216 lat=smolGetLatticeIndexNT(sim,lattice);
2217 LCHECK(lat>=0,funcname,ECsame,NULL);
2218 simlattice=sim->latticess->latticelist[lat];
2219 if(number==0) return ECok;
2220 LCHECK(number>0,funcname,ECbounds,"nmolec cannot be negative");
2221 i=smolGetSpeciesIndexNT(sim,species);
2222 LCHECK(i>0,funcname,ECsame,NULL);
2223 LCHECK(number>=0,funcname,ECbounds,"number cannot be < 0");
2224 if(!lowposition)
2225 low = simlattice->min;
2226 else
2227 low=lowposition;
2228 if(!highposition)
2229 high = simlattice->max;
2230 else
2231 high=highposition;
2232 er=latticeaddmols(simlattice,number,i,low,high,sim->dim);
2233 LCHECK(!er,funcname,ECmemory,"out of memory adding molecules");
2234 return ECok;
2235 failure:
2236 return Liberrorcode; }
2237
2238 /* smolAddLatticePort */
smolAddLatticePort(simptr sim,const char * lattice,const char * port)2239 extern CSTRING enum ErrorCode smolAddLatticePort(simptr sim, const char *lattice, const char *port) {
2240 const char *funcname="smolAddLatticePort";
2241 int prt,lat;
2242 latticeptr simlattice;
2243 portptr simport;
2244
2245 LCHECK(sim,funcname,ECmissing,"missing sim");
2246 lat=smolGetLatticeIndexNT(sim,lattice);
2247 LCHECK(lat>=0,funcname,ECsame,NULL);
2248 simlattice=sim->latticess->latticelist[lat];
2249 prt=smolGetPortIndexNT(sim,port);
2250 LCHECK(prt>=0,funcname,ECsame,NULL);
2251 simport=sim->portss->portlist[prt];
2252 latticeaddport(simlattice,simport);
2253 return ECok;
2254 failure:
2255 return Liberrorcode; }
2256
2257
2258 /* smolAddLatticeSpecies */
smolAddLatticeSpecies(simptr sim,const char * lattice,const char * species)2259 extern CSTRING enum ErrorCode smolAddLatticeSpecies(simptr sim,const char *lattice, const char *species) {
2260 const char *funcname="smolAddLatticeSpecies";
2261 int er,i,lat;
2262 latticeptr simlattice;
2263
2264 LCHECK(sim,funcname,ECmissing,"missing sim");
2265 lat=smolGetLatticeIndexNT(sim,lattice);
2266 LCHECK(lat>=0,funcname,ECsame,NULL);
2267 simlattice=sim->latticess->latticelist[lat];
2268 i=smolGetSpeciesIndexNT(sim,species);
2269 LCHECK(i>0,funcname,ECsame,NULL);
2270 er=latticeaddspecies(simlattice,i,NULL);
2271 LCHECK(!er,funcname,ECmemory,"out of memory in latticeaddspecies");
2272 return ECok;
2273 failure:
2274 return Liberrorcode; }
2275
2276 /* smolAddLatticeReaction */
smolAddLatticeReaction(simptr sim,const char * lattice,const char * reaction,const int move)2277 extern CSTRING enum ErrorCode smolAddLatticeReaction(simptr sim,const char *lattice, const char *reaction, const int move) {
2278 const char *funcname="smolAddLatticeReaction";
2279 int er,lat,r,order;
2280 latticeptr simlattice;
2281 rxnptr rxn;
2282
2283 LCHECK(sim,funcname,ECmissing,"missing sim");
2284 lat=smolGetLatticeIndexNT(sim,lattice);
2285 LCHECK(lat>=0,funcname,ECsame,NULL);
2286 simlattice=sim->latticess->latticelist[lat];
2287 order=-1;
2288 r=smolGetReactionIndexNT(sim,&order,reaction);
2289 LCHECK(r>=0,funcname,ECsame,NULL);
2290 rxn=sim->rxnss[order]->rxn[r];
2291
2292 er=latticeaddrxn(simlattice,rxn,move);
2293 LCHECK(!er,funcname,ECmemory,"out of memory in latticeaddrxn");
2294 return ECok;
2295 failure:
2296 return Liberrorcode; }
2297