NEURON
kinunit.cpp
Go to the documentation of this file.
1 #include <../../nmodlconf.h>
2 #include "model.h"
3 #include "symbol.h"
4 #include "units.h"
5 #include "parse1.hpp"
6 extern char *indepunits;
7 static List *reactnames;
8 
9 static void set_flux_units(unit*);
10 static void react_unit_err(char*, unit*);
11 
12 void kinunits(Item* type, int pass)
13 {
14  struct unit ux1, ux2, ur1, ur2, uflux;
15  Item *q;
16  char *s;
17 
18  if (type->itemsubtype == REACT1) {
19  ucopypop(&ux2);
20  }
21  ucopypop(&ux1);
22  if (type->itemsubtype == REACT1) {
23  ucopypop(&ur2);
24  }
25  ucopypop(&ur1);
26  if (pass == 0) {
27  return;
28  }
29 
30  /* case reaction with no numbers */
31  /* should check that all states have same units */
32  Unit_push((char *)0); /* this will go to any units */
33  ITERATE(q, reactnames) {
34  unit_push(ITM(q));
35  s = (char *)(ITMA(SYM(ITM(q))->info)[6]);
36  if (s) {
37  Unit_push(s);
38  unit_mul();
39  }
40  if (unit_diff()) {
41 Fprintf(stderr, "REACTION quantity units for %s is: %s\n", SYM(ITM(q))->name, unit_str());
42  unit_pop();
43 Fprintf(stderr, "but the quantity units of the first term is: %s\n", unit_str());
44  diag("Inconsistent material quantity units\n",
45  "Need a correct COMPARTMENT statement");
46  }
47  }
48 
50  unit_div();
51  ucopypop(&uflux);
52  set_flux_units(&uflux);
53 
54  if (type->itemsubtype == REACT1 || type->itemsubtype == '-') {
55  ucopypush(&ux1);
56  ucopypush(&uflux);
57  ucopypush(&ur1);
58  unit_div();
59  if (unit_diff()) {
60  react_unit_err("forward", &uflux);
61  }
62  unit_pop();
63  }
64 
65  if (type->itemsubtype == REACT1) {
66  ucopypush(&ux2);
67  ucopypush(&uflux);
68  ucopypush(&ur2);
69  unit_div();
70  if (unit_diff()) {
71  react_unit_err("backward", &uflux);
72  }
73  unit_pop();
74  }
75 
76  if (type->itemsubtype == LT) {
77  ucopypush(&ux1);
78  ucopypush(&uflux);
79  if (unit_diff()) {
80 Fprintf(stderr, "Flux units are: %s\n", Unit_str(&uflux));
81 Fprintf(stderr, "But users << flux units are:%s\n", Unit_str(&ux1));
82 diag("Inconsistent flux units", (char *)0);
83  }
84  unit_pop();
85  }
86 
87  freelist(&reactnames);
88 }
89 
90 static void set_flux_units(unit* up)
91 {
92  Symbol *s;
93 
94  Sprintf(buf, "%s", Unit_str(up));
95  if ((s = lookup("f_flux")) == SYM0) {
96  s = install("f_flux", NAME);
97  }
98  s->u.str = stralloc(buf, (char *)0);
99  if ((s = lookup("b_flux")) == SYM0) {
100  s = install("b_flux", NAME);
101  }
102  s->u.str = stralloc(buf, (char *)0);
103 
104 }
105 
106 static void react_unit_err(char* s, unit* up)
107 {
108 
109  Fprintf(stderr, "Flux units for this reaction: %s\n", Unit_str(up));
110  ucopypop(up);
111  Fprintf(stderr, "This implies %s rate units: %s\n", s, Unit_str(up));
112  ucopypop(up);
113 Fprintf(stderr, "But the users %s rate units are: %s\n", s, Unit_str(up));
114  diag("inconsistent reaction units", (char *)0);
115 }
116 
118  SYMITER_STAT {
119  ITMA(s->info)[6] = ITEM0;
120  }}
121 }
122 
124 {
125  char *ustr;
126 
127  ustr = (char *)(ITMA(SYM(q)->info)[6]);
128  if (ustr) {
129  diag(SYM(q)->name, "already in previous COMPARTMENT");
130  }
131  ITMA(SYM(q)->info)[6] = (Item *) stralloc(unit_str(), (char *)0);
132 }
133 
134 void unit_ldifuslist(Item* q, int flag)
135 {
136  char *ustr;
137  unitonflag = flag;
138  ustr = (char *)(ITMA(SYM(q)->info)[6]);
139  if (!ustr) {
140  diag(SYM(q)->name, "not declared in previous COMPARTMENT");
141  }
142  Unit_push("micron4/ms");
143  if (!unit_cmp_exact()) {
144  unit_pop();
145 diag(unit_str(), ": relevant area * diffusion constant must\n be micron2 micron2/ms (1-21 m4/s)");
146  }
147  unit_pop();
148  Unit_push("micron2");
149  Unit_push(ustr);
150  if (!unit_cmp_exact()) {
151  diag(ustr, ": With LONGDITUDINAL_DIFFUSION the compartment \
152 volume\nmust be measured in micron3/micron (1-12 m2)");
153  }
154  unit_pop();
155  unit_pop();
156  unitonflag = 0;
157 }
158 
160 {
161  char* ustr;
162  unit_push(q);
163  if (SYM(q)->info) {
164  ustr = (char *)(ITMA(SYM(q)->info)[6]);
165  if (ustr) {
166  Unit_push(ustr);
167  unit_mul();
168  }
169  }
170 }
171 
173 {
174  if (!reactnames) {
175  reactnames = newlist();
176  }
177  Lappenditem(reactnames, q);
178 }
short itemsubtype
Definition: model.h:17
Definition: units.h:2
char * stralloc(char *buf, char *rel)
Definition: list.cpp:208
void clear_compartlist()
Definition: kinunit.cpp:117
short type
Definition: cabvars.h:10
void ureactadd(Item *q)
Definition: kinunit.cpp:172
void unit_mul()
Definition: units.cpp:377
#define diag(s)
Definition: fmenu.cpp:188
void unit_div()
Definition: units.cpp:393
char * unit_str()
#define ITERATE(itm, lst)
Definition: model.h:25
#define SYM(q)
Definition: model.h:86
#define SYMITER_STAT
Definition: symbol.h:14
void Unit_push(char *)
Definition: units.cpp:284
#define ITEM0
Definition: model.h:22
#define Fprintf
Definition: model.h:249
int unitonflag
Definition: units.cpp:44
static List * info
Definition: model.h:15
#define install
Definition: redef.h:82
_CONST char * s
Definition: system.cpp:74
static List * reactnames
Definition: kinunit.cpp:7
void unit_compartlist(Item *q)
Definition: kinunit.cpp:123
Definition: model.h:57
char * name
Definition: init.cpp:16
List * newlist()
Definition: list.cpp:50
static void react_unit_err(char *, unit *)
Definition: kinunit.cpp:106
void kinunits(Item *type, int pass)
Definition: kinunit.cpp:12
#define lookup
Definition: redef.h:90
#define Lappenditem
Definition: model.h:261
char * indepunits
Definition: declare.cpp:13
int unit_diff()
Definition: units.cpp:501
int unit_cmp_exact()
Definition: units.cpp:427
static void set_flux_units(unit *)
Definition: kinunit.cpp:90
void freelist(List **plist)
Definition: list.cpp:61
void consreact_push(Item *q)
Definition: kinunit.cpp:159
char * Unit_str(unit *up)
Definition: units.cpp:191
void unit_ldifuslist(Item *q, int flag)
Definition: kinunit.cpp:134
char buf[512]
Definition: init.cpp:13
void unit_pop()
Definition: units.cpp:216
void ucopypush(struct unit *)
Definition: units.cpp:273
#define Sprintf
Definition: model.h:248
union Symbol::@18 u
#define SYM0
Definition: model.h:74
size_t q
#define ITMA(q)
Definition: model.h:89
void unit_push(Item *)
Definition: units1.cpp:7
char * str
Definition: model.h:63
void ucopypop(struct unit *)
Definition: units.cpp:262
#define ITM(q)
Definition: model.h:88