NEURON
kinunit.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include "model.h"
3 #include "symbol.h"
4 #include "units.h"
5 #include "parse1.hpp"
6 extern const char* indepunits;
7 static List* reactnames;
8 
9 static void set_flux_units(unit*);
10 static void react_unit_err(const char*, unit*);
11 
12 void kinunits(Item* type, int pass) {
13  struct unit ux1, ux2, ur1, ur2, uflux;
14  Item* q;
15  char* s;
16 
17  if (type->itemsubtype == REACT1) {
18  ucopypop(&ux2);
19  }
20  ucopypop(&ux1);
21  if (type->itemsubtype == REACT1) {
22  ucopypop(&ur2);
23  }
24  ucopypop(&ur1);
25  if (pass == 0) {
26  return;
27  }
28 
29  /* case reaction with no numbers */
30  /* should check that all states have same units */
31  Unit_push((char*) 0); /* this will go to any units */
32  ITERATE(q, reactnames) {
33  unit_push(ITM(q));
34  s = (char*) (ITMA(SYM(ITM(q))->info)[6]);
35  if (s) {
36  Unit_push(s);
37  unit_mul();
38  }
39  if (unit_diff()) {
40  Fprintf(stderr,
41  "REACTION quantity units for %s is: %s\n",
42  SYM(ITM(q))->name,
43  unit_str());
44  unit_pop();
45  Fprintf(stderr, "but the quantity units of the first term is: %s\n", unit_str());
46  diag("Inconsistent material quantity units\n", "Need a correct COMPARTMENT statement");
47  }
48  }
49 
51  unit_div();
52  ucopypop(&uflux);
53  set_flux_units(&uflux);
54 
55  if (type->itemsubtype == REACT1 || type->itemsubtype == '-') {
56  ucopypush(&ux1);
57  ucopypush(&uflux);
58  ucopypush(&ur1);
59  unit_div();
60  if (unit_diff()) {
61  react_unit_err("forward", &uflux);
62  }
63  unit_pop();
64  }
65 
66  if (type->itemsubtype == REACT1) {
67  ucopypush(&ux2);
68  ucopypush(&uflux);
69  ucopypush(&ur2);
70  unit_div();
71  if (unit_diff()) {
72  react_unit_err("backward", &uflux);
73  }
74  unit_pop();
75  }
76 
77  if (type->itemsubtype == LT) {
78  ucopypush(&ux1);
79  ucopypush(&uflux);
80  if (unit_diff()) {
81  Fprintf(stderr, "Flux units are: %s\n", Unit_str(&uflux));
82  Fprintf(stderr, "But users << flux units are:%s\n", Unit_str(&ux1));
83  diag("Inconsistent flux units", (char*) 0);
84  }
85  unit_pop();
86  }
87 
89 }
90 
91 static void set_flux_units(unit* up) {
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 static void react_unit_err(const char* s, unit* up) {
106  Fprintf(stderr, "Flux units for this reaction: %s\n", Unit_str(up));
107  ucopypop(up);
108  Fprintf(stderr, "This implies %s rate units: %s\n", s, Unit_str(up));
109  ucopypop(up);
110  Fprintf(stderr, "But the users %s rate units are: %s\n", s, Unit_str(up));
111  diag("inconsistent reaction units", (char*) 0);
112 }
113 
115  SYMITER_STAT {
116  ITMA(s->info)[6] = ITEM0;
117  }
118 }
119 }
120 
122  char* ustr;
123 
124  ustr = (char*) (ITMA(SYM(q)->info)[6]);
125  if (ustr) {
126  diag(SYM(q)->name, "already in previous COMPARTMENT");
127  }
128  ITMA(SYM(q)->info)[6] = (Item*) stralloc(unit_str(), (char*) 0);
129 }
130 
131 void unit_ldifuslist(Item* q, int flag) {
132  char* ustr;
133  unitonflag = flag;
134  ustr = (char*) (ITMA(SYM(q)->info)[6]);
135  if (!ustr) {
136  diag(SYM(q)->name, "not declared in previous COMPARTMENT");
137  }
138  Unit_push("micron4/ms");
139  if (!unit_cmp_exact()) {
140  unit_pop();
141  diag(unit_str(),
142  ": relevant area * diffusion constant must\n be micron2 micron2/ms (1-21 m4/s)");
143  }
144  unit_pop();
145  Unit_push("micron2");
146  Unit_push(ustr);
147  if (!unit_cmp_exact()) {
148  diag(ustr,
149  ": With LONGDITUDINAL_DIFFUSION the compartment \
150 volume\nmust be measured in micron3/micron (1-12 m2)");
151  }
152  unit_pop();
153  unit_pop();
154  unitonflag = 0;
155 }
156 
158  char* ustr;
159  unit_push(q);
160  if (SYM(q)->info) {
161  ustr = (char*) (ITMA(SYM(q)->info)[6]);
162  if (ustr) {
163  Unit_push(ustr);
164  unit_mul();
165  }
166  }
167 }
168 
169 void ureactadd(Item* q) {
170  if (!reactnames) {
171  reactnames = newlist();
172  }
174 }
char buf[512]
Definition: init.cpp:13
static void set_flux_units(unit *)
Definition: kinunit.cpp:91
static List * reactnames
Definition: kinunit.cpp:7
void unit_compartlist(Item *q)
Definition: kinunit.cpp:121
void ureactadd(Item *q)
Definition: kinunit.cpp:169
const char * indepunits
Definition: declare.cpp:10
void clear_compartlist()
Definition: kinunit.cpp:114
void kinunits(Item *type, int pass)
Definition: kinunit.cpp:12
void consreact_push(Item *q)
Definition: kinunit.cpp:157
void unit_ldifuslist(Item *q, int flag)
Definition: kinunit.cpp:131
static void react_unit_err(const char *, unit *)
Definition: kinunit.cpp:105
#define Lappenditem
Definition: model.h:223
#define SYM0
Definition: model.h:63
#define ITERATE(itm, lst)
Definition: model.h:18
const char * unit_str()
Definition: units.cpp:319
#define ITEM0
Definition: model.h:15
#define ITM(q)
Definition: model.h:77
#define SYM(q)
Definition: model.h:75
#define ITMA(q)
Definition: model.h:78
Symbol * lookup(const char *)
Symbol * install(const char *, int)
int unitonflag
Definition: units.cpp:34
const char * name
Definition: init.cpp:16
char * stralloc(const char *buf, char *rel)
Definition: list.cpp:178
#define SYMITER_STAT
Definition: symbol.h:22
void ucopypop(struct unit *)
Definition: units.cpp:270
void unit_pop()
Definition: units.cpp:225
void Unit_push(const char *)
Definition: units.cpp:290
void unit_mul()
Definition: units.cpp:364
void unit_push(Item *)
Definition: units1.cpp:7
void ucopypush(struct unit *)
Definition: units.cpp:280
void unit_div()
Definition: units.cpp:380
List * newlist()
The following routines support the concept of a list.
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
Definition: wrap_sprintf.h:14
static List * info
#define diag(s)
Definition: nonlin.cpp:19
size_t q
s
Definition: multisend.cpp:521
short type
Definition: cabvars.h:10
const char * Unit_str(unit *up)
Definition: units.cpp:194
int unit_cmp_exact()
Definition: units.cpp:412
int unit_diff()
Definition: units.cpp:485
Definition: model.h:8
Definition: model.h:47
Definition: units.h:2
int Fprintf(FILE *stream, const char *fmt, Args... args)
Definition: logger.hpp:8