-
Notifications
You must be signed in to change notification settings - Fork 0
/
units.scm
162 lines (138 loc) · 5.59 KB
/
units.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
;; Definitions for units of measurement
(define-unit-prefix milli second ms)
(define-unit-prefix milli volt mV)
(define-unit-prefix milli amp mA)
(define-unit-prefix pico amp pA)
(define-unit-prefix nano amp nA)
(define-unit-prefix micro amp uA)
(define-unit-prefix micro siemens uS)
(define-unit-prefix milli siemens mS)
(define-unit-prefix milli mole mM)
(define-unit-prefix mega ohm )
(define-unit-prefix kilo ohm kohm)
(define-quantity CurrentDensity (/ Current Area))
(define-quantity CapacitanceDensity (/ Capacitance Area))
(define-quantity ConductanceDensity (/ Conductance Area))
(define-quantity Resistivity (* Resistance Length))
(define-quantity ReactionRate1 (** Time -1))
(define-quantity ReactionRate2 (* (** Substance -1) (** Time -1)))
(define-quantity InversePotential (** Potential -1))
(define-quantity InversePotentialTime (* (** Potential -1) (** Time -1)))
(define-unit milliamp-per-square-centimeter CurrentDensity (/ mA (* cm cm)) mA/cm2)
(define-unit microfarad-per-square-centimeter CapacitanceDensity (/ uF (* cm cm)) uf/cm2)
(define-unit siemens-per-square-centimeter ConductanceDensity (/ S (* cm cm)) S/cm2)
(define-unit ohm.cm Resistivity (* ohm cm) ohm.cm)
(define-unit degC Temperature 1.0)
(define-unit /ms ReactionRate1 1000.0)
(define-unit /mM-ms ReactionRate2 1000000.0)
(define-unit /mV InversePotential 1000.0)
(define-unit /mV-ms InversePotentialTime 1000000.0)
(define-unit Hz Frequency 1.0)
(define model-units
(make-parameter
(map cons
`(second kilogram volt ampere coulomb farad ohm siemens mole molarity hertz
ms mV mA/cm2 pA nA uA mA mM uF uf/cm2 um S/cm2 uS mS ohm.cm ohm kohm megaohm degC /ms /mM-ms /mV /mV-ms Hz)
(list second kilogram volt ampere coulomb farad ohm siemens mole molarity hertz
ms mV mA/cm2 pA nA uA mA mM uF uf/cm2 um S/cm2 uS mS ohm.cm ohm kohm megaohm degC /ms /mM-ms /mV /mV-ms Hz))
))
(define model-quantities
(make-parameter
(map cons
`(Time Area Volume Temperature
Potential Current Capacitance Conductance Resistance
CurrentDensity
CapacitanceDensity
ConductanceDensity
Resistivity
ReactionRate1
ReactionRate2
InversePotential
InversePotentialTime
)
(list Time Area Volume Temperature
Potential Current Capacitance Conductance Resistance
CurrentDensity
CapacitanceDensity
ConductanceDensity
Resistivity
ReactionRate1
ReactionRate2
InversePotential
InversePotentialTime
))
))
(define (eval-dim-expr expr left? env)
(match expr
((op x y)
(let ((x1 (eval-dim-expr x #t env))
(y1 (eval-dim-expr y #f env)))
(case op
((^) (* x1 y1))
((*) (+ x1 y1))
((/) (- x1 y1))
(else (error 'eval-dim-expr "unknown quantity operation " op)))))
(x
(cond
((symbol? x)
(let ((assoc (assv x env)))
(if assoc
(eval-dim-expr (cdr assoc) left? env)
(error 'eval-dim-expr "unknown quantity" x))
))
((quantity? x)
(quantity-int x))
((and (not left?) (integer? x)) x)
((and left? (integer? x))
(error 'eval-dim-expr
"integers are not allowed as the left operand of quantity expression" expr))
(else (error 'eval-dim-expr "unknown quantity" x))))
))
(define (eval-unit-factor expr env)
(match expr
((op x y)
(let ((x1 (eval-unit-factor x env))
(y1 (eval-unit-factor y env)))
(case op
((*) (* x1 y1))
((/) (/ x1 y1))
(else (error 'eval-unit-factor "unknown unit factor operation " op)))))
((op x . y)
(eval-unit-factor `(,op ,(eval-unit-factor `(,op ,x ,(car y)) env) ,(cdr y)) env))
(x (cond
((symbol? x)
(let ((assoc (assv x env)))
(if assoc
(eval-unit-factor (cdr assoc) env)
(error 'eval-unit-factor "unknown unit" x))
))
((unit? x)
(unit-factor x))
((number? x) x)
(else (error 'eval-unit-factor "unknown unit" x))))
(else (error 'eval-unit-factor "invalid unit factor expression" expr))
))
(define (dim-unit-factor expr env)
(match expr
((op x y)
(let ((x1 (dim-unit-factor x env))
(y1 (dim-unit-factor y env)))
(case op
((*) (+ x1 y1))
((/) (- x1 y1))
(else (error 'dim-unit-factor "unknown unit factor operation " op)))))
((op x . y)
(dim-unit-factor `(,op ,(dim-unit-factor `(,op ,x ,(car y)) env) ,(cdr y)) env))
(x (cond
((symbol? x)
(let ((assoc (assv x env)))
(if assoc
(dim-unit-factor (cdr assoc) env)
(error 'dim-unit-factor "unknown unit" x))
))
((unit? x)
(quantity-int (unit-dims x)))
((number? x) 0)
(else (error 'dim-unit-factor "unknown unit " x))))
(else (error 'dim-unit-factor "invalid unit factor expression" expr))
))