root/trunk/units/si.d

Revision 515, 5.9 kB (checked in by BCS, 5 years ago)

added some values, units, types and operators/function

Line 
1 /**
2  * Set of real world units to work with
3  */
4 module si;
5
6 import std.string;
7
8 import unit;
9 import rational;
10
11 /// generate an encoder and decoder
12 template Option(char[] name, real v, int l, int m, int t, int T, int i)
13 {
14     const char[] ls = l.stringof;
15     const char[] ms = m.stringof;
16     const char[] ts = t.stringof;
17     const char[] Ts = T.stringof;
18     const char[] Is = i.stringof;
19     const char[] type = "Unit!("~ls~",1,"~ms~",1,"~ts~",1,"~Ts~",1,"~Is~",1)";
20    
21     /// unit encoder: stuff the value in the correct type with convertions
22     const char[] Make =
23         "static "~type~name~"(real val)"
24         "{"~
25             type~" ret;"
26             "ret._rawSet(val*"~v.stringof~");"
27             "return ret;"
28         "}"
29         "static "~type~name~"()"
30         "{"~
31             type~" ret;"
32             "ret._rawSet("~v.stringof~");"
33             "return ret;"
34         "}"
35         \n;
36    
37     /// unit decoder: if the unit classes match, create a function that extracts, converts and returns the value.
38     const char[] From =
39         "static if(is(T == "~type~"))"
40         "{"
41             "real "~name~"()"
42             "{"
43                 "return t._rawGet()/"~v.stringof~";"
44             "}"
45         "}"
46         \n;
47     //pragma(msg,From);
48 }
49
50 /// unwinds a set of unit defs into an implemntation of encoders or decoders
51 template BuildSet(char[] suf, T...)
52 {
53     static if(T.length == 0)
54         const BuildSet = "";
55     else static if (T.length == 1)
56         const BuildSet = (mixin(`Option!(`~T[0]~`).`~suf));
57     else
58         const BuildSet = BuildSet!(suf,T[0..$/2]) ~ BuildSet!(suf,T[$/2..$]);
59 }
60
61 /// The set of unit defs
62 alias Tpl!(
63     `"value",    1.0, 0,0,0,0,0`,
64     `"meter",    1.0, 1,0,0,0,0`,
65     `"kilogram", 1.0, 0,1,0,0,0`,
66     `"second",   1.0, 0,0,1,0,0`,
67     `"kelvin",   1.0, 0,0,0,1,0`,
68     `"ampere",   1.0, 0,0,0,0,1`,
69    
70     /// Distance Unit Types
71     `"Angstrom", 1e-10,             1,0,0,0,0`,
72     `"Micron",   1e-6,              1,0,0,0,0`,
73     `"mm",       1e-3,              1,0,0,0,0`,
74     `"cm",       1e-2,              1,0,0,0,0`,
75     `"km",       1e3,               1,0,0,0,0`,
76     `"inch",     2.54e-2,           1,0,0,0,0`,
77     `"foot",     3.04799835e-1,     1,0,0,0,0`,
78     `"yard",     9.14399506e-1,     1,0,0,0,0`,
79     `"mile",     1.609343130e3,     1,0,0,0,0`,
80     `"parsec",   3.085677473598e13, 1,0,0,0,0`,
81    
82     /// Mass Unit Types
83     `"gram",  1e-3,        0,1,0,0,0`,
84     `"lb",    4.5359237e-1,0,1,0,0,0`,
85     `"Ounce", 2.834952e-2, 0,1,0,0,0`,
86    
87     /// Time Unit Types
88     `"minute", 60.0,    0,0,1,0,0`,
89     `"hour",   3600.0,  0,0,1,0,0`,
90     `"day",    86400.0, 0,0,1,0,0`,
91    
92     /// Temperature Unit Types
93     `"R", 0.5555555555, 0,0,0,1,0`,
94    
95     /// Force  Unit Types
96     `"Newton", 1.0,           1,1,-2,0,0`,
97     `"dyne",   1e-5,          1,1,-2,0,0`,
98     `"lbf",    4.44822246806, 1,1,-2,0,0`,
99    
100     /// Charge Unit Types
101     `"Coulomb", 1.0, 0,0,1,0,1`,
102    
103     /// Magnetic flux density
104     `"T", 1.0, 0,1,-2,0,-1`,
105
106     /// magnetic flux
107     `"Wb", 1.0, 2,1,-2,0,1`,
108    
109     /// inductance
110     `"H", 1.0, 2,1,-2,0,-2`,
111    
112     /// Energy Unit Types
113     `"Joule", 1.0,              2,1,-2,0,0`,
114     `"Erg",   1e-7L,            2,1,-2,0,0`,
115     `"cal",   4.1868L,          2,1,-2,0,0`,
116     `"eV",    1.602176462e-19L, 2,1,-2,0,0`,
117     `"BTU",   1.0550558526e3L,  2,1,-2,0,0`,
118    
119     /// Voltage Unit Types
120     `"Volt", 1.0, 2,1,-3,0,-1`,
121    
122     /// Frequency Unit Types
123     `"Hz", 1.0, 0,0,-1,0,0`,
124    
125     /// Resistance Unit Types
126     `"Ohm", 1.0, -2,-1,3,0,2`,
127    
128     /// Pressure Unit Types
129     `"Pa",  1.0,         -1,1,-2,0,0`,
130     `"Bar", 1e5L,        -1,1,-2,0,0`,
131     `"Atm", 1.01325e5L,  -1,1,-2,0,0`,
132     `"psi", 6.89475729e3,-1,1,-2,0,0`,
133    
134     /// Viscosity
135     //
136     `"Poise",  0.1,    -1,1,-1,0,0`,
137     //
138     `"stokes", 0.0001,  2,0,-1,0,0`,
139    
140     /// Power Unit Types
141     `"Watt", 1.0,          2,1,-3,0,0`,
142     `"kWatt", 1000,        2,1,-3,0,0`,
143     `"Hp",   745.69987158L,2,1,-3,0,0`,
144    
145     /// Volume Unit Types
146     `"Steres", 1.0,          3,0,0,0,0`,
147     `"Liter",  0.001L,       3,0,0,0,0`,
148     `"Gal",    0.0037854120L,3,0,0,0,0`,
149     `"Cup",    0.0002365883L,3,0,0,0,0`,
150
151     /// volume rate
152     `"gpm",    6.30901995e-5L, 3,0,-1,0,0`,
153     `"cfm",    4.71947443e-4L, 3,0,-1,0,0`,
154
155     /// Speed Unit Types
156     `"mps",   1L,       1,0,-1,0,0`,
157     `"Knots", 1.51444L, 1,0,-1,0,0`,
158     `"mph",   0.44704L, 1,0,-1,0,0`,
159     `"kph",   0.27778L, 1,0,-1,0,0`,
160     `"fps",   0.3048L,  1,0,-1,0,0`,
161    
162     /// Capacitance Unit Types
163     `"Farad", 1.0, -2,-1,4,0,2`,
164    
165     /// Area Unit Types
166     `"Acre", 4046.856421L, 2,0,0,0,0`,
167    
168     /// Acceleration Unit Types
169     `"G", 9.80665L, 1,0,-2,0,0`
170
171     ) unitsSet;
172
173
174 static if(false)
175 {
176     pragma(msg,BuildSet!("Make", unitsSet));
177     pragma(msg,BuildSet!("From", unitsSet));
178 }
179
180
181 /// Name space to carry Unit encoders
182 struct SI
183 {
184     mixin(BuildSet!("Make", unitsSet));
185
186     static Unit!( 0,1, 0,1, 0,1, 1,1, 0,1) degF(real val)
187     {
188         Unit!( 0,1, 0,1, 0,1, 1,1, 0,1) ret;
189         ret._rawSet(val*0.5555555555 + 273.15);
190         return ret;
191     }
192
193     static Unit!( 0,1, 0,1, 0,1, 1,1, 0,1) degC(real val)
194     {
195         Unit!( 0,1, 0,1, 0,1, 1,1, 0,1) ret;
196         ret._rawSet(val + 273.15);
197         return ret;
198     }
199
200 }
201
202 /// Type to build decoders on.
203 struct To_back(T)
204 {
205     T t;
206     mixin(BuildSet!("From", unitsSet));
207
208     static if(is(T == Unit!( 0,1, 0,1, 0,1, 1,1, 0,1)))
209     {
210         real degF() { return (t._rawGet()-273.15)/0.5555555555; }
211         real degC() { return  t._rawGet()-273.15; }
212     }
213
214 }
215
216 /// Wrap a unit in a To_Back and retun it
217 To_back!(T) From(T)(T t)
218 {
219     To_back!(T) ret;
220     ret.t = t;
221     return ret;
222 }
223
224 static if(!false)
225 {
226 import std.stdio;
227 unittest
228 {
229     //pragma(msg, Product!(SI.Meter,SI.Second).Div!(SI.Kilogram).stringof);
230     writef("1 meter is %s in\n",From(SI.meter(1)).inch());
231     /+
232     1 meter is 39.3701 in
233     +/
234    
235     auto force =    SI.lbf(10);
236     auto distance = SI.foot(1);
237     auto time =     SI.second(10);
238     auto energy = force * distance;
239     auto power = energy / time;
240     auto pressure = force/ distance.Pow!(2);
241
242     writef("force %s N\n",      From(force).Newton);
243     writef("energy %s Joule\n", From(energy).Joule);
244     writef("power %s Watt\n",   From(power).Watt);
245     writef("pressure %s Pa\n",   From(pressure).Pa);
246     /+
247     force 44.4822 N
248     energy 13.5582 Joule
249     power 135.582 Watt
250     pressure 4.13253 Pa
251     +/
252 }
253 void main(){}
254 }
Note: See TracBrowser for help on using the browser.