pulo 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/pulo.rb +28 -0
- data/lib/pulo/exceptions.rb +6 -0
- data/lib/pulo/figure/figure2d.rb +248 -0
- data/lib/pulo/figure/figure3d.rb +166 -0
- data/lib/pulo/formatting.rb +140 -0
- data/lib/pulo/frames/frame.rb +289 -0
- data/lib/pulo/frames/frame_cell.rb +83 -0
- data/lib/pulo/frames/frame_column.rb +149 -0
- data/lib/pulo/frames/frame_row.rb +87 -0
- data/lib/pulo/helpers.rb +1 -0
- data/lib/pulo/machine/hydraulics/pipe.rb +71 -0
- data/lib/pulo/machine/machines.rb +10 -0
- data/lib/pulo/machine/mechanics/moments_of_inertia.rb +64 -0
- data/lib/pulo/machine/steam/boiler.rb +61 -0
- data/lib/pulo/machine/steam/boiler_deaerator.rb +64 -0
- data/lib/pulo/machine/steam/deaerator.rb +37 -0
- data/lib/pulo/machine/steam/desuperheater.rb +29 -0
- data/lib/pulo/machine/steam/header.rb +20 -0
- data/lib/pulo/machine/steam/if97.rb +378 -0
- data/lib/pulo/machine/steam/steam_process.rb +27 -0
- data/lib/pulo/machine/steam/steam_turbine.rb +42 -0
- data/lib/pulo/machine/steam/water_steam.rb +229 -0
- data/lib/pulo/material/water.rb +34 -0
- data/lib/pulo/quantity/dimension.rb +63 -0
- data/lib/pulo/quantity/numeric_overloads.rb +217 -0
- data/lib/pulo/quantity/quantity.rb +285 -0
- data/lib/pulo/quantity/quantity_builder.rb +185 -0
- data/lib/pulo/quantity/quantity_definitions.rb +8 -0
- data/lib/pulo/quantity/quantity_definitions/area_volume.rb +73 -0
- data/lib/pulo/quantity/quantity_definitions/basic.rb +157 -0
- data/lib/pulo/quantity/quantity_definitions/electric.rb +22 -0
- data/lib/pulo/quantity/quantity_definitions/energy.rb +50 -0
- data/lib/pulo/quantity/quantity_definitions/fluids.rb +23 -0
- data/lib/pulo/quantity/quantity_definitions/force_power.rb +82 -0
- data/lib/pulo/quantity/quantity_definitions/rotation.rb +49 -0
- data/lib/pulo/quantity/quantity_definitions/value.rb +65 -0
- data/lib/pulo/quantity/quantity_definitions/velocity_acc_flow.rb +66 -0
- data/lib/pulo/quantity/quantity_groups/quantity_groups.rb +36 -0
- data/lib/pulo/quantity/unit.rb +45 -0
- data/lib/pulo/quantity_checker.rb +13 -0
- data/lib/pulo/tables/density.rb +10 -0
- data/lib/pulo/tables/melting_temperature.rb +9 -0
- data/lib/pulo/tables/specific_energy.rb +10 -0
- data/lib/pulo/tables/speed_of_sound.rb +9 -0
- data/lib/pulo/tables/tables.rb +104 -0
- data/lib/pulo/tables/tensile_strength.rb +10 -0
- data/lib/pulo/tables/yield_strength.rb +10 -0
- data/lib/pulo/version.rb +3 -0
- metadata +51 -3
@@ -0,0 +1,285 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Pulo
|
4
|
+
#Module instance variables to store global settings
|
5
|
+
class << self
|
6
|
+
attr_accessor :precision
|
7
|
+
attr_accessor :significant_figures
|
8
|
+
attr_accessor :supress_quantity_names
|
9
|
+
|
10
|
+
def quantities; @quantities||={};end #hash with dimension_spec as the key
|
11
|
+
|
12
|
+
def help
|
13
|
+
@quantities.each do |dim|
|
14
|
+
|
15
|
+
dim[1].each do |quan|
|
16
|
+
names=quan.quantity_name
|
17
|
+
if quan.synonyms.length>0
|
18
|
+
names += ', ' + quan.synonyms.join(', ')
|
19
|
+
end
|
20
|
+
|
21
|
+
puts names
|
22
|
+
puts '---------------------------------------------------------------------------------------'
|
23
|
+
puts '[' + dim[0].to_s + ']'
|
24
|
+
puts quan.units_sorted
|
25
|
+
puts ''
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
Pulo.precision = 2
|
32
|
+
Pulo.significant_figures = false
|
33
|
+
Pulo.supress_quantity_names = false
|
34
|
+
|
35
|
+
|
36
|
+
module Pulo
|
37
|
+
class Quantity
|
38
|
+
include Comparable
|
39
|
+
#=====================================
|
40
|
+
#Quantity: Class variables and methods - For child quantity classes
|
41
|
+
#=====================================
|
42
|
+
class << self
|
43
|
+
def units; @units ||={}; end
|
44
|
+
def si_unit_scales; @si_unit_scales ||={};end
|
45
|
+
def synonyms; @synonyms ||=[]; end
|
46
|
+
|
47
|
+
attr_accessor :base_unit
|
48
|
+
attr_accessor :dimensions
|
49
|
+
|
50
|
+
def best_si_unit(scale)
|
51
|
+
@si_unit_scales.min_by do |unit|
|
52
|
+
(scale-unit[0]).abs
|
53
|
+
end[1]
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_missing(method_sym, *arguments, &block)
|
57
|
+
puts "#{quantity_name} doesn't have a unit #{method_sym}."
|
58
|
+
puts "Available units are: " + units.map{|unt| unt[1].name }.join(', ')
|
59
|
+
end
|
60
|
+
|
61
|
+
def quantity_name
|
62
|
+
self.name.split('::')[1]
|
63
|
+
end
|
64
|
+
|
65
|
+
def units_sorted
|
66
|
+
self.units.values.sort do |a,b|
|
67
|
+
next -1 if a.is_si? && !b.is_si?
|
68
|
+
|
69
|
+
next 1 if !a.is_si? && b.is_si?
|
70
|
+
|
71
|
+
if a.is_si?
|
72
|
+
next -1 if a.scale<b.scale
|
73
|
+
next 1
|
74
|
+
else
|
75
|
+
if a.si_convert_unit==b.si_convert_unit
|
76
|
+
next a.si_convert_factor<=>b.si_convert_factor
|
77
|
+
else
|
78
|
+
a.si_convert_unit<=>b.si_convert_unit
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
#=====================================
|
86
|
+
#Instance variables and methods - Child Quantities
|
87
|
+
#=====================================
|
88
|
+
attr_accessor :value, :unit
|
89
|
+
|
90
|
+
def initialize(value=nil, unit=nil)
|
91
|
+
value ||= 1.0
|
92
|
+
if unit
|
93
|
+
if unit.is_a?(Symbol)
|
94
|
+
raise "Unit #{unit.to_s} not defined for #{self.class.quantity_name}." unless self.class.units[unit]
|
95
|
+
|
96
|
+
self.unit=self.class.units[unit]
|
97
|
+
else
|
98
|
+
self.unit=unit
|
99
|
+
end
|
100
|
+
else
|
101
|
+
self.unit=self.class.base_unit
|
102
|
+
end
|
103
|
+
self.value=Float(value) unless self.value.is_a?(Float)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
def dimensions
|
108
|
+
self.class.dimensions
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_s(precision=nil, supress_quantity_names=false)
|
112
|
+
"#{self.class.quantity_name + ': ' unless Pulo.supress_quantity_names || supress_quantity_names || self.class==Dimensionless}#{NumberToRoundedConverter.convert(@value,precision)} #{@unit.abbreviation}"
|
113
|
+
end
|
114
|
+
|
115
|
+
def to; self; end
|
116
|
+
def in; self; end
|
117
|
+
|
118
|
+
#Pass unknown methods through to the underlying value (Float) if it responds. eg floor and modulo methods
|
119
|
+
def method_missing(method_sym, *arguments, &block)
|
120
|
+
if self.value.respond_to?(method_sym)
|
121
|
+
self.value.send(method_sym,*arguments,&block)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def inverse
|
126
|
+
Dimensionless.new/self
|
127
|
+
end
|
128
|
+
def -@
|
129
|
+
self.class.new -self.value,self.unit
|
130
|
+
end
|
131
|
+
def +(other)
|
132
|
+
case
|
133
|
+
when other.is_a?(Numeric)
|
134
|
+
self.class.new self.value+other,self.unit
|
135
|
+
when other.class.dimensions==self.class.dimensions
|
136
|
+
if self.unit==other.unit
|
137
|
+
self.class.new self.value+other.value,self.unit
|
138
|
+
else
|
139
|
+
self.class.new self.value+other.send(self.unit.name).value,self.unit
|
140
|
+
end
|
141
|
+
else
|
142
|
+
raise QuantitiesException.new("Cannot add a #{other.class.name} to a #{self.class.name}")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
def -(other)
|
146
|
+
case
|
147
|
+
when other.is_a?(Numeric)
|
148
|
+
self.class.new self.value-other,self.unit
|
149
|
+
when other.class.dimensions==self.class.dimensions
|
150
|
+
if self.unit==other.unit
|
151
|
+
self.class.new self.value-other.value,self.unit
|
152
|
+
else
|
153
|
+
self.class.new self.value-other.send(self.unit.name).value,self.unit
|
154
|
+
end
|
155
|
+
else
|
156
|
+
raise QuantitiesException.new("Cannot minus a #{other.class.name} from a #{self.class.name}")
|
157
|
+
end
|
158
|
+
end
|
159
|
+
def *(other)
|
160
|
+
case
|
161
|
+
when other.is_a?(Numeric)
|
162
|
+
self.class.new self.value*other,self.unit
|
163
|
+
when other.is_a?(Quantity)
|
164
|
+
new_dims=self.class.dimensions+other.class.dimensions
|
165
|
+
|
166
|
+
#get both quantities to their equivalent SI if needed
|
167
|
+
q1=self; q1=q1.to_si unless q1.is_si?
|
168
|
+
q2=other; q2=q2.to_si unless q2.is_si?
|
169
|
+
|
170
|
+
target_scale=q1.unit.scale+q2.unit.scale
|
171
|
+
target_value=q1.value*q2.value
|
172
|
+
existing_or_new_quantity new_dims,target_scale,target_value
|
173
|
+
else
|
174
|
+
raise QuantitiesException.new("Cannot multiply a #{other.class.name} and a #{self.class.name}")
|
175
|
+
end
|
176
|
+
end
|
177
|
+
def /(other)
|
178
|
+
case
|
179
|
+
when other.is_a?(Numeric)
|
180
|
+
self.class.new self.value/other,self.unit
|
181
|
+
when other.is_a?(Quantity)
|
182
|
+
new_dims=self.class.dimensions-other.class.dimensions
|
183
|
+
|
184
|
+
q1=self; q1=q1.to_si unless q1.is_si?
|
185
|
+
q2=other; q2=q2.to_si unless q2.is_si?
|
186
|
+
|
187
|
+
target_scale=q1.unit.scale-q2.unit.scale
|
188
|
+
target_value=q1.value/q2.value
|
189
|
+
existing_or_new_quantity new_dims,target_scale,target_value
|
190
|
+
else
|
191
|
+
raise QuantitiesException.new("Cannot divide a #{self.class.name} by a #{other.class.name}")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
def **(power)
|
195
|
+
raise QuantitiesException.new('Can only raise a quantity to an integer power') unless power.is_a?(Integer)
|
196
|
+
|
197
|
+
new_dims=self.class.dimensions*power
|
198
|
+
q1=self; q1=q1.to_si unless q1.is_si?
|
199
|
+
|
200
|
+
target_scale=q1.unit.scale*power
|
201
|
+
target_value=q1.value**power
|
202
|
+
|
203
|
+
existing_or_new_quantity new_dims,target_scale,target_value
|
204
|
+
end
|
205
|
+
def rt(power)
|
206
|
+
raise QuantitiesException.new('Can only do integer roots') unless power.is_a?(Integer)
|
207
|
+
|
208
|
+
self.class.dimensions.spec.each do |dim|
|
209
|
+
if dim[1]/power.to_f % 1 != 0
|
210
|
+
raise QuantitiesException.new('Root would lead to non-integer dimensions')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
new_dims=self.class.dimensions/power
|
214
|
+
|
215
|
+
q1=self; q1=q1.to_si unless q1.is_si?
|
216
|
+
|
217
|
+
target_scale=q1.unit.scale/power
|
218
|
+
target_value=q1.value**(1.0/power)
|
219
|
+
existing_or_new_quantity new_dims,target_scale,target_value
|
220
|
+
end
|
221
|
+
def <=>(other)
|
222
|
+
unless (other.is_a?(Quantity) && self.class.dimensions==other.class.dimensions) || (other.is_a?(Numeric) && self.class==Dimensionless)
|
223
|
+
raise QuantitiesException.new("Can only compare quantities with same dimensions (given: #{self.class} and #{other.class}).")
|
224
|
+
end
|
225
|
+
if other.is_a?(Numeric)
|
226
|
+
other=Dimensionless.n(other)
|
227
|
+
end
|
228
|
+
to_base_unit.value<=>other.to_base_unit.value
|
229
|
+
end
|
230
|
+
|
231
|
+
def existing_or_new_quantity(new_dims, target_scale, target_value)
|
232
|
+
if Pulo.quantities[new_dims]
|
233
|
+
klass=Pulo.quantities[new_dims][0]
|
234
|
+
unit=klass.best_si_unit Math.log10(target_value.abs) + target_scale
|
235
|
+
klass.new(target_value*10**(target_scale-unit.scale), unit)
|
236
|
+
else
|
237
|
+
qname=new_dims.to_s(true).gsub(/-/, '_')
|
238
|
+
QuantityBuilder.build(qname) do
|
239
|
+
# noinspection RubyArgCount
|
240
|
+
dimensions new_dims.spec
|
241
|
+
si_unit '0.0'+qname, '', new_dims.to_s, 1.0
|
242
|
+
unless target_scale==0
|
243
|
+
si_unit target_scale.to_s+qname, '', new_dims.to_s+'*10^'+target_scale.to_s, 1.0*10**target_scale
|
244
|
+
end
|
245
|
+
end.klass.send(target_scale.to_s+qname, target_value)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def to_base_unit
|
250
|
+
self.send(self.class.base_unit.name)
|
251
|
+
end
|
252
|
+
|
253
|
+
def is_si?
|
254
|
+
@unit.is_si?
|
255
|
+
end
|
256
|
+
|
257
|
+
def to_si
|
258
|
+
return self if self.is_si?
|
259
|
+
self.send(self.unit.si_convert_unit)
|
260
|
+
end
|
261
|
+
|
262
|
+
#Converts to SI and most 'natural' scale
|
263
|
+
def rescale
|
264
|
+
unless self.is_si?
|
265
|
+
return self.to_base_unit.rescale
|
266
|
+
end
|
267
|
+
scale=Math.log10(self.value)+self.unit.scale
|
268
|
+
|
269
|
+
unit_scales=self.class.si_unit_scales.sort
|
270
|
+
|
271
|
+
if scale<unit_scales[0][0]
|
272
|
+
return self.send unit_scales[0][1].name
|
273
|
+
end
|
274
|
+
if scale>=unit_scales.last[0]
|
275
|
+
return self.send unit_scales.last[1].name
|
276
|
+
end
|
277
|
+
unit_scales.each_cons(2) do |us|
|
278
|
+
if us[0][0]<=scale && us[1][0]>scale
|
279
|
+
return self.send us[0][1].name
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Pulo
|
4
|
+
class QuantityBuilder
|
5
|
+
|
6
|
+
@unit_group_name
|
7
|
+
|
8
|
+
def self.build(name,&block)
|
9
|
+
klass=Class.new(Quantity)
|
10
|
+
Pulo.const_set(name,klass)
|
11
|
+
QuantityBuilder.new(klass,&block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(klass,&block)
|
15
|
+
@klass=klass
|
16
|
+
instance_eval(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def klass
|
20
|
+
@klass
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def define_method_on_klass(klass,method, &block)
|
26
|
+
klass.send :define_method, method, &block
|
27
|
+
end
|
28
|
+
|
29
|
+
def dimensions(*dims)
|
30
|
+
#Create a dimensions object based on the supplied specification and set it on the new class
|
31
|
+
spec=Dimension.new(dims[0])
|
32
|
+
@klass.dimensions=spec
|
33
|
+
|
34
|
+
if Pulo.quantities[spec]
|
35
|
+
#If a quantity has already been defined with this set of dimensions
|
36
|
+
|
37
|
+
Pulo.quantities[spec].each do |quan_klass|
|
38
|
+
#for each of the other quantities with the same dimensions
|
39
|
+
# define a method on them with the name of this quantity
|
40
|
+
quan_klass.instance_exec(@klass) do |other_klass|
|
41
|
+
define_method other_klass.quantity_name.downcase do
|
42
|
+
other_unit=other_klass.si_unit_scales[self.unit.scale]
|
43
|
+
other_unit=other_klass.best_si_unit(Math.log10(self.value)+self.unit.scale) unless other_unit
|
44
|
+
return other_klass.new(self.value*10**(self.unit.scale-other_unit.scale),other_unit)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#and define a method on us for the reverse
|
49
|
+
define_method_on_klass @klass, quan_klass.quantity_name.downcase do
|
50
|
+
other_unit=quan_klass.si_unit_scales[self.unit.scale]
|
51
|
+
other_unit=quan_klass.best_si_unit(Math.log10(self.value)+self.unit.scale) unless other_unit
|
52
|
+
return quan_klass.new(self.value*10**(self.unit.scale-other_unit.scale),other_unit)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
Pulo.quantities[spec] << @klass
|
56
|
+
else
|
57
|
+
Pulo.quantities.merge!({spec=>[@klass]})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def synonyms(*synonyms)
|
62
|
+
synonyms.each do |synonym|
|
63
|
+
@klass.synonyms << synonym
|
64
|
+
Pulo.const_set(synonym,@klass.clone)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def constant(name,symbol,unit,value)
|
69
|
+
@klass.define_singleton_method(name) do
|
70
|
+
# noinspection RubyArgCount
|
71
|
+
self.new value, self.units[unit]
|
72
|
+
end
|
73
|
+
unless symbol==''
|
74
|
+
@klass.define_singleton_method(symbol) do
|
75
|
+
# noinspection RubyArgCount
|
76
|
+
self.new value, self.units[unit]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def si_unit(name,plural,abbreviation,scale)
|
82
|
+
scale=Math.log10(scale)
|
83
|
+
unit=SI_Unit.new(name,plural, abbreviation,scale)
|
84
|
+
if scale==0
|
85
|
+
@klass.base_unit=unit
|
86
|
+
end
|
87
|
+
define_unit_methods unit
|
88
|
+
@klass.si_unit_scales.merge!({scale=>unit})
|
89
|
+
end
|
90
|
+
|
91
|
+
def non_si_unit(name,plural,abbreviation,si_convert_unit,si_convert_factor)
|
92
|
+
unit=NonSI_Unit.new(name,plural, abbreviation, si_convert_unit, si_convert_factor)
|
93
|
+
define_unit_methods unit
|
94
|
+
end
|
95
|
+
|
96
|
+
def define_unit_methods(unit)
|
97
|
+
@klass.units.merge!({unit.name=>unit})
|
98
|
+
|
99
|
+
#Class method for creating by unit name
|
100
|
+
@klass.define_singleton_method("#{unit.name}") do |val|
|
101
|
+
# noinspection RubyArgCount
|
102
|
+
self.new val,unit
|
103
|
+
end
|
104
|
+
|
105
|
+
#Class method for creating by unit plural name
|
106
|
+
unless unit.name.to_s==unit.plural
|
107
|
+
@klass.define_singleton_method("#{unit.plural}") do |val|
|
108
|
+
self.send(unit.name,val) #Could also be done as a method alias?
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
#Class method for creating by unit abbreviated name
|
113
|
+
unless unit.name.to_s==unit.abbreviation || unit.abbreviation==''
|
114
|
+
@klass.define_singleton_method("#{unit.abbreviation}") do |val|
|
115
|
+
self.send(unit.name,val) #Could also be done as a method alias?
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
#Instance method for conversion to this unit by plural
|
120
|
+
unless unit.name.to_s==unit.plural
|
121
|
+
define_method_on_klass(@klass,"#{unit.plural}") do
|
122
|
+
self.send(unit.name) #Could also be done as a method alias?
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
#Instance method for conversion to this unit by abbreviation
|
127
|
+
unless unit.name.to_s==unit.abbreviation || unit.abbreviation==''
|
128
|
+
define_method_on_klass(@klass,"#{unit.abbreviation}") do
|
129
|
+
self.send(unit.name) #Could also be done as a method alias?
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
define_method_on_klass(@klass,"#{unit.name}") do
|
134
|
+
#If its conversion to and from the same unit then just return self
|
135
|
+
if self.unit.name==unit.name ##TODO: Make == work for units
|
136
|
+
return self
|
137
|
+
end
|
138
|
+
|
139
|
+
#Actual conversions depending on si or non-si from and to units
|
140
|
+
case
|
141
|
+
|
142
|
+
#si to si
|
143
|
+
when self.unit.is_si? && unit.is_si?
|
144
|
+
# noinspection RubyArgCount
|
145
|
+
self.class.new self.value*10**(self.unit.scale-unit.scale),unit
|
146
|
+
|
147
|
+
#si to non-si
|
148
|
+
when self.unit.is_si? && !unit.is_si?
|
149
|
+
to_unit=self.class.units[unit.name]
|
150
|
+
if to_unit.si_convert_unit==self.unit.name
|
151
|
+
intermediate_si=self
|
152
|
+
else
|
153
|
+
intermediate_si=self.send(to_unit.si_convert_unit)
|
154
|
+
end
|
155
|
+
# noinspection RubyArgCount
|
156
|
+
self.class.new intermediate_si.value*to_unit.si_convert_factor,unit
|
157
|
+
|
158
|
+
#non-si to si
|
159
|
+
when !self.unit.is_si? && unit.is_si?
|
160
|
+
# noinspection RubyArgCount
|
161
|
+
intermediate_si=self.class.new self.value/self.unit.si_convert_factor,self.class.units[self.unit.si_convert_unit]
|
162
|
+
if intermediate_si.unit==unit
|
163
|
+
intermediate_si
|
164
|
+
else
|
165
|
+
intermediate_si.send(unit.name)
|
166
|
+
end
|
167
|
+
|
168
|
+
#non-si to non-si
|
169
|
+
else
|
170
|
+
#get the destination non-si unit definition
|
171
|
+
to_unit=self.class.units[unit.name]
|
172
|
+
|
173
|
+
#first convert self to si
|
174
|
+
intermediate_si=self.send(self.unit.si_convert_unit)
|
175
|
+
|
176
|
+
#then convert this si to the si 'partner' of the destination unit
|
177
|
+
intermediate_si2=intermediate_si.send(to_unit.si_convert_unit)
|
178
|
+
|
179
|
+
#lastly convert this to the final required non-si
|
180
|
+
intermediate_si2.send(to_unit.name)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|