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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
|
##############################################################################
#
# Copyright (c) 2003-2020 by The University of Queensland
# http://www.uq.edu.au
#
# Primary Business: Queensland, Australia
# Licensed under the Apache License, version 2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# Development until 2012 by Earth Systems Science Computational Center (ESSCC)
# Development 2012-2013 by School of Earth Sciences
# Development from 2014 by Centre for Geoscience Computing (GeoComp)
# Development from 2019 by School of Earth and Environmental Sciences
#
##############################################################################
from __future__ import print_function, division
"""
:synopsis: some tools supporting physical units and conversion
:var Yotta: prefix yotta, symbol: Y
:var Zetta: prefix zetta, symbol: Z
:var Exa: prefix exa, symbol: E
:var Peta: prefix peta, symbol: P
:var Tera: prefix tera, symbol: T
:var Giga: prefix giga, symbol: G
:var Mega: prefix mega, symbol: M
:var Kilo: prefix kilo, symbol: k
:var Hecto: prefix hecto, symbol: h
:var Deca: prefix deca, symbol: da
:var Deci: prefix deci, symbol: d
:var Centi: prefix centi, symbol: c
:var Milli: prefix milli, symbol: m
:var Micro: prefix micro, symbol: mu
:var Nano: prefix nano, symbol: n
:var Pico: prefix pico, symbol: p
:var Femto: prefix femto, symbol: f
:var Atto: prefix atto, symbol: a
:var Zepto: prefix zepto, symbol: z
:var Yocto: prefix yocto, symbol: y
:var km: unit of kilo meter
:var m: unit of meter
:var cm: unit of centi meter
:var mm: unit of milli meter
:var sec: unit of second
:var msec: unit of milli second
:var minute: unit of minute
:var h: unit of hour
:var hour: unit of hour
:var day: unit of day
:var yr: unit of year
:var Myr: unit of mega year
:var Gyr: unit of giga year
:var gram: unit of gram
:var kg: unit of kilo gram
:var lb: unit of pound
:var ton: metric ton
:var A: unit of Ampere
:var Hz: unit of Hertz (frequenacy)
:var N: unit of Newton (force)
:var Pa: unit of Pascal (pressure, stress)
:var bar: unit of bar (pressure)
:var atm: unit of atmosphere (pressure)
:var J: unit of Joule (energy, work)
:var W: unit of Watt (power)
:var C: unit of Coulomb (electric charge)
:var V: unit of Volt (electric potential)
:var F: unit of Farad (capacitance)
:var Ohm: unit of Ohm (electric resistance)
:var K: unit of Kelvin (temperature)
:var Mol: unit of Mole (temperature)
:var Celsius: unit of Celsius (temperature)
:var Fahrenheit: unit of Fahrenheit (temperature)
:var Poise: unit of Poise (dynamic viscosity)
:var R_Earth_equator: Earth's equatorial radius
:var R_Earth_poles: Earth's polar radius
:var R_Earth: Earth's radius
:var v_light: speed of light
:var pi: value of pi accurate to 10 decimal places
:var Gravitational_Constant: gravitational constant
"""
__copyright__="""Copyright (c) 2003-2020 by The University of Queensland
http://www.uq.edu.au
Primary Business: Queensland, Australia"""
__license__="""Licensed under the Apache License, version 2.0
http://www.apache.org/licenses/LICENSE-2.0"""
__url__="https://launchpad.net/escript-finley"
__author__="Lutz Gross, l.gross@uq.edu.au"
## :file unitsSI.py
from math import pi
class Unit(object):
"""
a general class to define a physical unit and convert from this unit to an appropriate SI unit.
`Unit` object have a dual purpose: Firstly physical units can be combined through *,/ and ** to form new physical units or to add prefixes such as
Milli to m to form mm=Milli*m. Moreover, a given floating point number x (or any other arithmetic object) can be converted from the physical unit to
the SI system, eg. 10*mm to create the value for 10mm which is the float number 0.01 in the SI system. In addition, a value in the SI unit can be
converted back to the given unit, eg. to express 0.01m in physical units of mm use 0.01/mm which will return 10.
"""
def __init__(self, name, longname,a ,b ):
"""
initializes the physical unit
:param name: short name of the physical unit or prefix
:type name: ``str``
:param longname: long name of the physical unit or prefix
:type longname: ``str``
:param a: absolute value in transformation
:type a: ``float``
:param b: slop in translation
:type b: ``float``
"""
self.setName(name)
self.setLongName(longname)
self.__a=a
self.__b=b
def __str__(self):
return self.getName()
def getName(self):
"""
Returns the name of the physical unit
:return: name of the physical unit
:rtype: ``str``
"""
return self.__name
def setName(self, name):
"""
Sets the name of the physical unit
:param name: new name of the physical unit
:type name: ``str``
"""
self.__name=name
def getLongName(self):
"""
Returns the long name of the physical unit
:return: name of the physical unit
:rtype: ``str``
"""
return self.__longname
def setLongName(self, name):
"""
Sets the long name of the physical unit
:param name: new long name of the physical unit
:type name: ``str``
"""
self.__longname=name
def __call__(self,x):
"""
Converts a value x in the physical unit self to SI
:param x: value to convert
:type x: an arithmetic object
"""
return self.__b*x+self.__a
def __mul__(self,other):
"""
Performs self*other operation for two `Unit` objects
:param other: an other physical unit
:type other: `Unit`
:rtype: `Unit` or ``NotImplemented``
"""
if isinstance(other, Unit):
a=self(other(0.))
b=(self(other(1.))-a)
if isinstance(other, _PowUnit) or isinstance(self,_DivUnit) or isinstance(self, _PowUnit):
return _ProdUnit(self.getName()+" "+other.getName(),self.getLongName()+"*"+other.getLongName(),a ,b)
else:
return _ProdUnit(self.getName()+other.getName(),self.getLongName()+"*"+other.getLongName(),a ,b)
else:
return NotImplemented
def __rmul__(self,other):
"""
Performs other*self operation
:param other: an other `Unit` or an arithmetic object. if other is a arithmetic object such as ``float`` other is assumed to be given in the physical unit ``self`` and is converted into the corresponding SI unit.
:type other: `Unit` or
:rtype: `Unit` of or an arithmetic object
"""
if isinstance(other, Unit):
a=other(self(0.))
b=(other(self(1.))-a)
if isinstance(other, _PowUnit) or isinstance(self, _PowUnit) or isinstance(other, _DivUnit):
return _ProdUnit(other.getName()+" "+self.getName(),other.getLongName()+"*"+self.getLongName(),a ,b)
else:
return _ProdUnit(other.getName()+self.getName(),other.getLongName()+"*"+self.getLongName(),a ,b)
else:
return self(other)
#Need this for python2
def __div__(self, other):
return self.__truediv__(other)
def __truediv__(self,other):
"""
Performs self*other operation for two `Unit` objects
:param other: an other physical unit
:type other: `Unit`
:rtype: `Unit` or ``NotImplemented``
"""
if isinstance(other, Unit):
if abs(self(0.))+abs(other(0.))>0:
raise ValueError("Division of physical units requires 0 absolute values")
if isinstance(other, (_ProdUnit, _DivUnit)):
# X/(c*d) or X/(c/d) requires brackets:
return _DivUnit(self.getName()+"/("+other.getName()+")",self.getLongName()+"/("+other.getLongName()+")",0 , self(1.)/other(1.))
else:
return _DivUnit(self.getName()+"/"+other.getName(),self.getLongName()+"/"+other.getLongName(),0 , self(1.)/other(1.))
else:
return NotImplemented
#Need this for python2
def __rdiv__(self, other):
return self.__rtruediv__(other)
def __rtruediv__(self,other):
"""
Performs other/self operation
:param other: an other `Unit` or an arithmetic object
:type other: `Unit` or an arithmetic object
:rtype: `Unit` or an arithmetic object
"""
if isinstance(other, Unit):
if abs(self(0.))+abs(other(0.))>0:
raise ValueError("Division of physical units requires 0 absolute values")
if isinstance(self, (_ProdUnit, _DivUnit)):
# X/(a*b) or X/(a/b) requires brackets:
return _DivUnit(other.getName()+"/("+self.getName()+")",other.getLongName()+"/("+self.getLongName()+")",0 , other(1.)/self(1.))
else:
return _DivUnit(other.getName()+"/"+self.getName(),other.getLongName()+"/"+self.getLongName(),0 , other(1.)/self(1.))
else:
return (other-self(0.))/(self(1.)-self(0.))
def __pow__(self,other):
"""
Performs self**other operation
:param other: an exponent
:type other: ``int`` or ``float``
:rtype: `Unit`
"""
if isinstance(other, float) or isinstance(other, int):
if abs(self(0.))>0:
raise ValueError("Power of physical unit requires 0 absolute values")
if isinstance(self, (_ProdUnit, _DivUnit, _PowUnit)):
return _PowUnit("("+self.getName()+")^%s"%other, "("+self.getLongName()+")^%s"%other, 0., self(1.)**other)
else:
return _PowUnit(self.getName()+"^%s"%other, self.getLongName()+"^%s"%other, 0., self(1.)**other)
else:
return NotImplemented
class _ProdUnit(Unit):
pass
class _DivUnit(Unit):
pass
class _PowUnit(Unit):
pass
#
# prefixes:
#
Yotta=Unit("Y","Yotta",0.,1.e24)
Zetta=Unit("Z","Zetta",0.,1.e21)
Exa=Unit("E","Exa",0.,1.e18)
Peta=Unit("P","Peta",0.,1.e15)
Tera=Unit("T","Tera",0.,1.e12)
Giga=Unit("G","Giga",0.,1.e9)
Mega=Unit("M","Mega",0.,1.e6)
Kilo=Unit("k","Kilo",0.,1.e3)
Hecto=Unit("h","Hecto",0.,1.e2)
Deca=Unit("da","Deca",0.,1.e1)
one=Unit("1","1",0.,1.)
Deci=Unit("d","Deci",0.,1.e-1)
Centi=Unit("c","Centi",0.,1.e-2)
Milli=Unit("m","Milli",0.,1.e-3)
Micro=Unit("mu","Micro",0.,1.e-6)
Nano=Unit("n","Nano",0.,1.e-9)
Pico=Unit("p","Pico",0.,1.e-12)
Femto=Unit("f","Femto",0.,1.e-15)
Atto=Unit("a","Atto",0.,1.e-18)
Zepto=Unit("z","Zepto",0.,1.e-21)
Yocto=Unit("y","Yocto",0.,1.e-24)
#
# length
#
m=Unit("m","meter",0.,1.)
km=Kilo*m
cm=Centi*m
mm=Milli*m
liter=(Deci*m)**3
ft=Unit("ft", "feet", 0., 0.3048 * m)
Barrel=Unit("bbl","barrel", 0., 0.158987294928 * m**3)
Mscf=Unit("MSCF", "thousand standard cubic feet", 0., 28.31685 * m**3)
Mcf=1000. * ft**3
ccm=cm**3
#
# time
#
sec=Unit("sec","second",0.,1.)
msec=Unit("msec","milli-second",0.,1e-3)
minute=Unit("min","minute",0.,60.)
hour=Unit("h","hour",0.,60.* minute)
h=hour
day=Unit("d","day",0., 24. * h)
yr=Unit("yr","year",0.,365.2425 * day)
year=yr
Myr=Mega*yr
Gyr=Giga*yr
#
# mass
#
kg=Unit("kg","kg",0.,1.)
gram=Milli*kg
lb=Unit("lb","pound",0.,0.45359237 * kg)
ton=Kilo*kg
#
# electric current
#
A=Unit("A","Ampere",0.,1.)
#
# Temperature
#
K=Unit("K","Kelvin",0.,1.)
Celsius=Unit("C","Celsius",273.15,1.)
Fahrenheit=Unit("F","Fahrenheit",459.67*5./9.,5./9.)
#
# others
#
Mol=Unit("mole","Mole",0.,1.)
Hz=one/sec
N = Unit("N","Newton",0.,1.)
Pa = Unit("Pa","Pascal",0.,1.)
bar=100*Kilo*Pa
atm= Unit("atm","atmosphere",0.,101325.024 * Pa)
psi= Unit("psi","Psi",0.,6894.75728034 * Pa)
J = Unit("J","Joule",0.,1.)
W= Unit("W","Watt",0.,1.)
C=Unit("C","Coulomb",0.,1.)
V = Unit("V","Volt",0.,1.)
F = Unit("F","Farad",0.,1.)
Ohm=Unit("Ohm","Ohm",0.,1.)
RAD=Unit("RAD","rad",0.,1.)
DEG=Unit("Ohm","Ohm",0.,pi/180.)
gal=Unit("gal","galileo",0.,0.01)
mgal=gal*Milli
Tesla=V*sec/(m**2)
T=Tesla
#
# Derived
#
Poise= gram/cm/sec
cPoise=Poise*Centi
mPoise=Poise*Milli
Darcy= 9.869233e-13*m**2
mDarcy=Darcy*Milli
#
# some constants
#
R_Earth_equator=6378.1370*km
R_Earth_poles=6356.7523*km
R_Earth=(R_Earth_equator+R_Earth_poles)/2
v_light=299792458.*m/sec
Mu_0 = 4 * pi * 10**(-7)*V*sec/A/m
Magnetic_Dipole_Moment_Earth = 8.22 * 10**22*A*m**2
Gravitational_Constant=6.6742e-11*m**3/(kg*sec**2)
|